Minotauro nº11:(TEXT_004.011):19/04/1997 << Back To Minotauro nº 11
MINOTAURO MAGAZINE #11 Descripcion del boot sector, FAT y sector de directorio by Zarpex En esta nota, pongo a disposicion de uds. todos los datos necesarios que fui aprendiendo y que hay que conocer sobre ... (bueno, habran leido el titulo, no? :) ) cualquier duda, dejen un msg.......NO! ARREGLENSELA! ;) a ver ... quien sabe como se formatea un disco o diskette? ALUMNO ULTRA LAMMER DEL IAC : - YO!! format x: donde x es la unidad Muy bien, pero si a este digamos, sujeto, se le preguntara que es el boot sector, seguramente se quedaria callado....obviamente no esperabamos mas de un tipo que paga $200 para aprender wincurr 95, word y demas sandeces (!?). Pero, cuantos de uds saben que es lo que permite a un diskette ser reconocido como valido por el dos para poder utilizarlo?? Bueno, todos mas o menos saben como esta dividido logicamente un disco o diskette, no? cuando se formatea, el disco queda dividido en cuatro areas bien diferenciadas: NOTA: esto del boot sector es MUY-DEMASIADO-EXTRA-CONOCIDISIMO, y lo pueden ---- saltear si quieren, ya que seguramente no les aportara nada nuevo. asi que a menos que recien empiezen o sean tan despistados como para nunca haber visto una descripcion del boot o ni siquiera haber usado el diskedit, sugiero que pasen al tema de la fat. Pero en fin, ahi va ... 1.- el boot sector, que contiene los datos necesarios para que el dos pueda acceder al disco duro y aparte tiene un pequeno programa encargado de cargar en memoria el io.sys, msdos.sys y transferirles el control. (o no. si no los encuentra muestra el mensaje para que se ponga un diskette con archivos de sistema) todo esto se encuentra en el sector logico 0. su archiconocida estructura es la siguiente: (siempre hay alguno que no la tiene...) en los primeros 62 bytes esta la BPB, (bios parameter block) que contiene varios datos importantes sobre el disco: ╔════════════╦════════╦═════════════════════════════════════════════════╗ ║ Offset ║ bytes ║ descripcion ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 0 ║ 3 ║ estos 3 bytes no son datos en realidad, sino ║ ║ ║ ║ que es un jmp al final de la tabla y al ║ ║ ║ ║ principio del codigo ejecutable ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 3 ║ 8 ║ OEM ID ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 0Bh ║ 2 ║ bytes per sector ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 0Dh ║ 1 ║ sectors per cluster ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 0Eh ║ 2 ║ reserved sectors at beggining ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 10h ║ 1 ║ FAT copies ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 11h ║ 2 ║ root directory entries ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 13h ║ 2 ║ total sectors on disk ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 15h ║ 1 ║ media descriptor byte ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 16h ║ 2 ║ sectors per FAT ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 18h ║ 2 ║ sectors per track ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1Ah ║ 2 ║ sides ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1Ch ║ 4 ║ special hidden sectors ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 20h ║ 4 ║ big total number of sectors ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 24h ║ 2 ║ physical drive number ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 26h ║ 1 ║ extended boot record signature ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 27h ║ 4 ║ volume serial number ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 2Bh ║ 11d ║ volume laberl ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 36h ║ 8 ║ file system ID ║ ╚════════════╩════════╩═════════════════════════════════════════════════╝ como broche final, en el offset 1FEh (al final del boot sector) esta la marca 55AAh que indican un boot valido. ahora, en el master boot record (tabla de particiones) hay otra tabla de datos (junto a su correspondiente codigo ejecutable que lo interpreta) ubicada en los ultimos 66 bytes del sector y comienza en el offset 1BEh. tambien en el offset 1FEh esta los bytes 55AAh. por ejemplo: ╔════════════╦════════╦═════════════════════════════════════════════════╗ ║ Offset ║ bytes ║ descripcion ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1BEh ║ 1 ║ boot ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1BFh ║ 1 ║ side ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C0h ║ 1 ║ sector ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C1h ║ 1 ║ cylinder ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C2h ║ 1 ║ system ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C3h ║ 1 ║ side ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C4h ║ 1 ║ sector ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C5h ║ 1 ║ cylinder ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1C6h ║ 4 ║ relative sectors ║ ╠════════════╬════════╬═════════════════════════════════════════════════╣ ║ 1CAh ║ 4 ║ number of sectors ║ ╚════════════╩════════╩═════════════════════════════════════════════════╝ 2.- despues de este programita, vienen las dos copias de la FAT. esta contiene todos los clusters asociados a cada archivo que se encuentra en el disco. por ejemplo, el archivo pepe.txt que comienza en tal cluster, para que el dos pueda accederlo, debe seguir la cadena de clusters por la que esta compuesto. (un cluster es la minima unidad que se reserva para un archivo) bueno, sabiendo lo mas basico, vamos a leer la FAT. para estar bien seguro de donde comienza la FAT, hay que leer el boot sector (supongo que conoceran la int 25h, no?) y leer el offset 0Eh para saber cuantos sectores de boot y reservados hay antes del comienzo de la FAT. veamos un ejemplo de como esta dispuesto un archivo en la FAT: primero, tenemos una entrada de directorio como la siguiente (en el punto 3 se describe a full como esta compuesta una de estas): ╔═══════╦═══╦═╦══════════╦══╦══╦══╦════╗ ║program║exe║a║ ║hh║dd║08║size║ ╚══╦════╩═╦═╩╦╩═════╦════╩╦═╩╦═╩╦═╩═╦══╝ ║ ║ ║ ║ hora dia║ tamano del nombre del ══════╝ ║ ║ ║ (2) (2)║ archivo (4) archivo (7) ║ ║ reservado ║ ║ ║ (10) ║ extension (3) ══════╝ ║ cluster atributo inicial (1) (2) entre parentesis esta la cantidad de bytes usados lo que nos interesa a nosotros (para leer la fat) es el offset nro 28 de una entrada de directorio que contiene el cluster inicial del archivo. en este caso, program.exe tiene su primer byte en el cluster nro 8 0 1 2 3 4 5 6 7 8 9 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 ╔══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╗ ║ID║ff║03║04║05║ff║00║00║09║0a║0b║15║00║00║00║00║00║00║00║00║00║16║17║19║f7║ ╚══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╝ 19 1a 1b 1c 1d 1e 1f ╔══╦══╦══╦══╦══╦══╦══╗ ║1a║1b║ff║00║00║00║00║ ╚══╩══╩══╩══╩══╩══╩══╝ eso de ahi arriba es un ejemplo de una porcion de la fat. entonces, si queremos ubicar a program.exe, vemos en que cluster comienza (en este caso 8) y leemos. por ejemplo, vamos a la entrada nro 8 y vemos que hay un 9, quiere decir que se sigue en el cluster nro 9. entonces al final, la cadena quedaria asi: 8,9,0a,0b,15,16,17,19,1a,1b. cada entrada marca la siguiente (o el final con un codigo especial) el cluster nro 18 esta marcado como "bad" y no interviene en la cadena. los clusters 6,7,0c-14 y 1c-1f estan vacios y se los puede utilizar para grabar informacion otra cadena comienza en el cluster 2 y termina en el 5 la fat puede venir (asi, de fabrica, nomas) en entradas de 12-bit o en 16-bit. las de 12-bit van para los diskettes, debido a que a pesar de ser eficientes, no sirven para discos grandes. por eso en discos duros se usa fat de 16 bit. las fat de 16 bit vienen desde el dos 3.0 por la necesidad de poder manejar los discos "nuevos" de 20mb. bueno, ahora, para leer los datos de la fat (para seguir una cadena, por ej.): primero, hay que leer la fat en memoria y obtener el cluster donde comienza el archivo (como ya vimos, de una entrada del directorio). despues, para fat de 12-bit: * multiplicar el nro. de cluster por 3 * al resultado, se lo divide por 2 * ese resultado, es un offset, en el cual hay que leer un word. (siempre ese offset es dentro de la fat, ok?) * si el cluster es par, enmascarar el resultado con 0fffh (guardar los 12 bits bajos) si el cluster es impar, hay que rotar a la derecha (shr) 4 bits (guardar los 12 bits altos) * y al fin, el resultado es el proximo cluster de la cadena (0fffh termina). para la fat de 16-bit es una boludez, sencillamente cada entrada contiene un offset de 16 bits hacia el proximo cluster (0fffh termina) ahora, la fat en su primer byte, tiene un byte denominado media descriptor o fat id byte. los proximos 5 bytes (en fat de 12 bit) o 7 bytes (en fat de 16 bit) son igual a 0ffh. el resto de la fat esta compuesto por "celdas" de 12 o 16 bit que representan un cluster del disco. cada una de estas puede contener uno de los siguientes valores: (0)000h..................cluster disponible (f)ff0h hasta (f)ff7h....cluster reservado (f)ff7h..................cluster danado (f)ff8h hasta (f)fffh....fin de una cadena (0)002h hasta (f)fefh....el numero del proximo cluster en una cadena puf! que laburo.....espero que sirva para algo...bueno, continuemos: una vez que tenemos un archivo, y tenemos su cluster inicial y todo, debemos ubicar ese file en disco, o sea, debemos ubicar que sector al-berga a ese file. bueno, para la conversion de cluster a sector, se utilizan las siguientes formulas: root_dir_sectors = sector_bytes / (root_dir_entries * 32) fat_sectors = fat_count * sectors_per_fat data_start = reserved_sectors + fat_sectors + root_dir_sectors int 25h/26h sector = data_start + ((any_cluster_number - 2) * sectors_per_cluster) donde las variables: sector_bytes sectors_per_fat fat_count root_dir_entries reserved_sectors sectors_per_cluster se pueden obtener del bpb explicado mas arriba. el numero de sector obtenido se puede pasar en dx de int 25h/26h para acceder al archivo. o, segun ralph brown, esta la funcion 32h de int 21h que predica asi: ;---------------------------------------------------------------------------- INT 21 - Internal - GET DRIVE PARAMETER BLOCK AH = 32h DL = drive number 0 = default, 1 = A, etc. Return: AL = 0FFh if invalid drive number, else DS:BX = address of drive parameter block. STRUCTURE OF DOS DRIVE PARAMETER BLOCK: DPBLOCK STRUCT ;OFFSET DISK_OFFSET DB ? ; 0. drive number (0 = A, etc.) UNIT_OFFSET DB ? ; 1. unit number within device driver SECTOR_SIZE DW ? ; 2. number of bytes per sector MAX_CLUSTER DB ? ; 4. largest sector number in cluster ; add one for number of sectors/cluster LOG2_SECTORS DB ? ; 5. log base two of the cluster size RESERVED DW ? ; 6. number of reserved (boot) sectors FAT_COUNT DB ? ; 8. number of copies of the FAT ROOT_COUNT DW ? ; 9. number of root directory entries DATA_START DW ? ; 11. first data sector on medium MAX_NUMBER DW ? ; 13. largest possible cluster number ; subtract one for number of data clusters FAT_SECTORS DB ? ; 15. number of sectors in one FAT copy ROOT_START DW ? ; 16. first sector of root directory DEVICE_ADDR DD ? ; 18. address of device driver for this drive DESCRIPTOR DB ? ; 22. media descriptor byte for medium VALID_BYTE DB ? ; 23. 0FFh indicates block must be rebuilt NEXT_BLOCK DD ? ; 24. address of next device block in list ; FROM THIS POINT ON, DOS 3 DIFFERS FROM 2: IF DOS2 DIR_START DW ? ; 28. starting cluster of current directory ; zero indicates the root directory PATH_NAME DB 64 DUP (?) ; 30. ASCIIZ current directory path string ELSE DOS3 ; on my XT, this was always: DW 0 DW 0FFFFh ENDIF DPBLOCK ENDS ;---------------------------------------------------------------------------- lo malo de esto es que es indocumentado (creo) asi que no se hasta cuando servira. pero igual ahorra laburo. bueno, eso es todo sobre la fat... 3.- y la ultima parte es el directorio raiz. aca estan los nombres y mucha otra informacion sobre cada uno de los archivos y directorios ubicados en el mismo. en realidad el directorio raiz y todos los subdirectorios, poseen las llamadas entradas de directorio que es lo que detalla esta tabla: ╔═══════════════════╦════════════════╦══════════════════════════════════╗ ║ offset ║ nro. bytes ║ descripcion ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 0 ║ 8 ║ nombre del archivo ena ASCII el ║ ║ ║ ║ primer byte puede contener esto: ║ ║ ║ ║ 00h -> entrada sin archivo ║ ║ ║ ║ E5h -> archivo borrado ║ ║ ║ ║ 2Eh -> subdirectorio ║ ║ ║ ║ cualquier otro valor es el nombre║ ║ ║ ║ del archivo. ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 8 ║ 3 ║ extension del archivo ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 11 ║ 1 ║ atributo del archivo: ║ ║ ║ ║ 01h -> solo lectura ║ ║ ║ ║ 02h -> oculto ║ ║ ║ ║ 04h -> sistema ║ ║ ║ ║ 08h -> etiqueta ║ ║ ║ ║ 10h -> subdirectorio ║ ║ ║ ║ 20h -> modificado despues del ║ ║ ║ ║ ultimo backup* ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 12 ║ 10 ║ reservado ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 22 ║ 2 ║ hora del archivo ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 24 ║ 2 ║ fecha del archivo ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 26 ║ 2 ║ cluster inicial ║ ╠═══════════════════╬════════════════╬══════════════════════════════════╣ ║ 28 ║ 4 ║ tamano del archivo ║ ╚═══════════════════╩════════════════╩══════════════════════════════════╝ * esto es seteado por backup y xcopy para saber que archivos fueron backupeados. 4.- bueno, no jodan. es obvio, aca empiezan los datos en si. en fin, espero que les haya sido util. asi por lo menos saben que carajo estan haciendo cuando escriben copy o abren un archivo o lo ejecutan. creo que esto es "la salsa" de todo esto y merece darse a conocer....snif! saludos............zarpex