Capítulo – 13
Lectura y modificación de MBR con programación
Registro de arranque de DOS (DBR) / Sector de arranque de DOS
Registro de arranque de DOS (DBR) / Sector de arranque de DOS
Después de la tabla de particiones, el Registro de arranque de DOS (DBR) o, a veces, llamado Sector de arranque de DOS es la segunda información más importante en su disco duro.
Para obtener un estudio detallado sobre DBR, consulte el capítulo "Enfoque lógico de los discos y el sistema operativo", analizado anteriormente en este libro.
El primer sector lógico de cada partición de DOS contendrá un registro de arranque de DOS (DBR) o un sector de arranque de DOS. El trabajo del DBR es cargar el sistema operativo desde el disco duro a la memoria principal de la computadora y dar el control del sistema al programa cargado.
El Registro de arranque de DOS (DBR) para la primera partición en un disco duro generalmente se encuentra en Absolute Sector 63 (el sector 64 en la unidad de disco) o en forma CHS podemos decir C–H–S = 0–1 –1 para la mayoría de las unidades.
Sin embargo, esta ubicación puede variar según el SPT (sectores por pista) de la unidad. Por ejemplo, en una unidad antigua de 245 MB que solo tenía 31 SPT, el registro de arranque estaba ubicado en el sector 32 (sector absoluto 31).
Dado que el disquete no tiene particiones, no tiene MBR ni tabla maestra de particiones en su primer sector, sino que contiene el DBR en su primer sector.
El DBR se crea con el comando FORMAT de DOS, después de realizar la partición con el comando FDISK. El sector en el que reside DBR se convierte en el sector lógico 1 de esa partición en particular para el DOS. El número de sector utilizado por DOS comienza desde el sector físico en el que se encuentra DBR.
El DBR contiene un pequeño programa que es ejecutado por el programa ejecutable Master Boot Record (MBR). Todas las particiones de DOS contienen el código del programa para iniciar la máquina, es decir, cargar el sistema operativo, pero el Registro de inicio maestro solo le da control a esa partición, que se especifica como partición activa, en la entrada de la tabla de particiones.
Si el DBR está dañado de alguna forma, la unidad debe estar accesible si inicia el sistema desde el disquete o CD de inicio. Aunque el disco duro no se puede iniciar (si el DBR de la partición activa está dañado), por lo general, eso no debería afectar el acceso a los datos de la unidad de disco. Después de iniciar el sistema con el disco de inicio, puede acceder a los datos.
/* Mostrar los parámetros de arranque del disquete */
# include <dos.h>
# include <stdio.h>
main( )
{
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ;/* OEM Name and Version*/
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Sectors Per Cluster */
int res_sec ; /* Reserved Sectors */
char fat_copies ; /* Number of FATs */
int root_dir_entry ; /* Number of Root
Directory Entries */
unsigned int no_sects ; /* Number of Sectors in
Logical Volume */
unsigned char format_id ; /* Media Descriptor Byte
*/
int sec_per_fat ; /* Sectors Per FAT */
int sec_per_trk ; /* Sectors Per Track */
int no_sides ; /* Number of Heads */
int no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned char rest_code[482] ; /* Rest of the code */
} ;
struct boot b ;
char temp[4] ;
int val, drive ;
val = absread(0, 1, 0, &b) ; /* Use For Floppy Disk*/
if ( val == -1 )
{
printf ( "Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
printf ( "System ID = %s\n",
b.system_id ) ;
printf ( "Bytes per sector = %d\n",
b.bytes_per_sec ) ;
printf ( "Sectors per cluster = %d\n",
b.sec_per_clus ) ;
printf ( "Reserved sectors = %d\n",
b.res_sec ) ;
printf ( "FAT copies = %d\n",
b.fat_copies ) ;
printf ( "Root directory entries = %d\n",
b.root_dir_entry ) ;
printf ( "No. of sectors on disk = %u\n",
b.no_sects ) ;
printf ( "Media Descriptor Byte = %X\n",
b.format_id ) ;
printf ( "Sectors per FAT = %d\n",
b.sec_per_fat ) ;
printf ( "Sectors per track = %d\n",
b.sec_per_trk ) ;
printf ( "No. of sides = %d\n",
b.no_sides ) ;
printf ( "No. of reserved sectors = %d\n",
b.no_sp_res_sect ) ;
return 0;
}
Si ejecuta este programa para probar el DBR de 1,44 M, disquete de 3½ pulgadas con 70 pistas, dos caras, 18 sectores por pista y 512 bytes en un sector, la salida del programa se mostrará de forma similar a la siguiente:
ID del sistema = +1<*uIHC
Bytes por sector = 512
Sectores por clúster = 1
Sectores reservados = 1
Copias FAT = 2
Entradas del directorio raíz = 224
No. de sectores en disco = 2880
Byte de descripción de medios = F0
Sectores por FAT = 9
Sectores por pista = 18
No. de lados = 2
No. de sectores reservados = 0
Lectura del DBR de grandes volúmenes
Los volúmenes de partición que tienen un tamaño superior a 32 MB tienen un formato diferente de DBR que el DBR para volúmenes menores o iguales a 32 MB.
Es así para brindar soporte a grandes volúmenes del disco (para obtener una descripción detallada, consulte el capítulo "Enfoque lógico de los discos y el sistema operativo", discutido anteriormente en este libro).
El formato del registro de arranque de DOS de un volumen FAT32 se proporciona en la siguiente tabla:
El siguiente programa es para leer el DBR de grandes volúmenes, que tienen un tamaño superior a 32 MB:
/* Programa para mostrar los parámetros de arranque de un volumen de disco grande */
# include "dos.h"
# include "stdio.h"
void main()
{
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ; /* OEM name & Version */
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Sectors Per Cluster*/
unsigned int res_sec ; /* Number of Reserved
Sectors */
char fat_copies ; /* Number of FATs */
unsigned int root_dir_entry ;/* Number of Root
Directory Entry */
unsigned int no_sects ; /* Number of Sectors in
Logical Volume (if
Volume is <= 32MB) */
unsigned char Media_id ; /* Media Descriptor Byte
*/
unsigned int sec_per_fat ; /* Sector Per FAT */
unsigned int sec_per_trk ; /* Sectors Per Track */
unsigned int no_sides ; /* Number of Heads */
unsigned long no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned long long_sec_num ; /* Total Sectors in
Logical Volume
( Size >32MB) */
unsigned long num_sec_per_FAT; /* Sectors Per FAT */
unsigned int binary_flags; /* Binary Flags */
unsigned char version_of_FAT1; /* First Byte of FAT
Version */
unsigned char version_of_FAT2; /* Second Byte of FAT
Version */
unsigned long root_dir_start_cluster;
/* Root Directory
Starting Cluster
Number */
unsigned int sec_num_of_file_sys;
/* Sector Number of
File System
Information Sector
*/
unsigned int sec_num_of_backup_boot_sec;
/* Sector Number of
Backup Boot Sector
*/
unsigned char reserved[12]; /* Reserved */
unsigned char logical_drive_number;
/* Physical Drive
Number of Logical
Volume */
unsigned char unused_byte; /* Unused Byte */
unsigned char hex_extd_boot_signature;
/* Extended Boot
Signature(29H) */
unsigned long binary_volume_ID;/* Binary Volume ID */
unsigned char volume_label[11];/* Volume Label */
unsigned char FAT_name[8]; /* FAT Name */
unsigned char rest_code[420] ; /* Rest 420 Bytes of
The DBR */
unsigned char magic_number[2]; /* Magic Number */
} ;
struct boot b ;
char temp[4] ;
int val, drive,i;
val = biosdisk( 2, 0x80, 1,0,1,1, &b ) ;
/* For First Hard Disk */
if ( val == -1 )
{
printf ( "Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
printf ( " Jump Instruction Code = ");
for(i=0;i<=2;i++)
{
printf("%X",b.code[i]);
}
printf("(H)\n ");
printf ( "OEM name and version = %s\n ",
b.system_id ) ;
printf ( "Bytes per sector = %u\n ",
b.bytes_per_sec ) ;
printf ( "Sectors per cluster = %u\n ",
b.sec_per_clus ) ;
printf ( "Reserved sectors = %u\n ",
b.res_sec ) ;
printf ( "FAT copies = %d\n ",
b.fat_copies ) ;
printf ( "Root directory entries = %u\n ",
b.root_dir_entry ) ;
printf ( "No. of sectors on disk = %u\n ",
b.no_sects ) ;
printf ( "Media Descriptor Byte = %X(H)\n",
b.Media_id ) ;
printf ( "Sectors per FAT = %u\n ",
b.sec_per_fat ) ;
printf ( "Sectors per track = %u\n ",
b.sec_per_trk ) ;
printf ( "No. of sides = %u\n ",
b.no_sides ) ;
printf ( "No. of reserved (Hidden) sectors= %lu\n ",
b.no_sp_res_sect ) ;
printf ( "========== For Large(>32MB) Disks ========\n");
printf ( "No. of sectors,(if Volume is >32MB) = %lu\n ",
b.long_sec_num) ;
printf ( “Number of Sectors Per FAT = %lu\n “,
b.num_sec_per_FAT );
printf ( "Root Directory Starting Cluster = %lu\n ",
b.root_dir_start_cluster);
printf ( "File System Information Sector = %u\n ",
b.sec_num_of_file_sys);
printf ( "Sector Number of Backup Boot Sector = %u\n ",
b.sec_num_of_backup_boot_sec);
printf ( "Physical Drive Number = %X(H)\n",
b.logical_drive_number);
printf ( "Extended Boot Signature = %X(H)\n",
b.hex_extd_boot_signature);
printf ( "32-Bit Binary Volume ID = ");
Decimal_to_Binary (b.binary_volume_ID,32);
printf ( " (B)\n ");
printf ( "Volume Label = ");
for(i=0;i<=10;i++)
{
printf ( "%c",b.volume_label[i]);
}
printf ( "\n FAT name = ");
for(i=0;i<=7;i++)
{
printf ( "%c",b.FAT_name[i]);
}
printf ( "\n ");
printf ( "Magic Number = %X%X(H)",
b.magic_number[0],b.magic_number[1]);
getch();
}
//////// Función de conversión de decimal a binario \\\\\\\\
Decimal_to_Binary(unsigned long input)
{
unsigned long i;
int count = 0;
int binary [32]; /* 32 Bit MAX only 32
elements total */
do
{
i = input%2; /* MOD 2 to get 1 or a 0*/
binary[count] = i; /* Load Elements into the
Binary Array */
input = input/2; /* Divide input by 2 to
decrement via binary */
count++; /* Count howy elements
are needed */
}while (input > 0);
/* Dígitos binarios inversos y de salida */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
Cuando el programa se ejecuta para leer el DBR de un gran volumen, la salida del programa se muestra de la siguiente manera:
Código de instrucción de salto = EB5890 (H)
Nombre y versión del OEM = MSWIN4.1
Bytes por sector = 512
Sectores por clúster = 8
Sectores reservados = 32
copias FAT = 2
Entradas del directorio raíz = 0
N.º de sectores en disco = 0
Byte descriptor de medios = F8 (H)
Sectores por FAT = 0
Sectores por pista = 63
N.º de lados = 255
Número de sectores reservados (ocultos) = 63
=========== Para discos grandes (>32 MB) ===========
Número de sectores (si el volumen es >32 MB) = 11277567
Número de sectores por FAT = 11003
Clúster de inicio del directorio raíz = 2
Sector de información del sistema de archivos = 1
Número de sector del sector de arranque de copia de seguridad = 6
Número de unidad física = 80 (H)
Firma de arranque extendida = 29 (H)
ID de volumen binario de 32 bits = 110101010001100001110111100101 (B)
Etiqueta de volumen = SAAYA
nombre FAT = FAT32
Número mágico = 55AA (H)
En la salida del programa vemos que los siguientes parámetros se muestran cero:
- Entrada de directorio raíz
- Número de sectores en disco
- Número de sectores por FAT
Estos parámetros son así porque estos valores se establecen en cero, si el volumen de la partición tiene un tamaño superior a 32 MB y la información real se encuentra en el Bloque de información de volumen extendido del DBR.
Por ejemplo, en la parte inicial de la información de DBR, la cantidad de sectores por FAT es 0 y en el bloque de información de volumen extendido de DBR, la cantidad de sectores por FAT es 11003, que es el valor real para este gran volumen .
El DBR del volumen tiene información importante sobre los parámetros del disco, que se puede utilizar para vincular toda la información de datos con fines de programación. Por ejemplo, si desea acceder a los DBR de otro volumen de Partición en el disco, puede calcularlo por una cantidad de sectores, escritos en DBR y otra información relacionada.
Si desea acceder al enfoque Disco con clúster, puede realizar cálculos con la ayuda de Sectores por clúster, sectores por FAT y otra información.
Si utiliza un disco duro de más de 8,4 GB (consulte el capítulo "Enfoque lógico de los discos y el sistema operativo", analizado anteriormente en este libro), utilice extensiones para acceder a todos los DBR del disco que superen los 8,4 GB. Consulte las funciones extendidas de lectura y escritura, dadas en los capítulos anteriores.
Cómo recuperar DBR con programación
Puede recuperar el DBR del volumen del disco hasta el 100 por ciento utilizando algunos enfoques complicados y cálculos lógicos. Como discutimos los enfoques lógicos de los sistemas de archivos en el capítulo, "Enfoque lógico de los discos y el sistema operativo", anteriormente en este libro, cada información en DBR está escrita dentro de algún límite o regla.
Cada parámetro escrito en el DBR tiene algún significado específico y se escribe siguiendo alguna regla y razón específicas. Es por eso que la información de DBR, si se pierde, se puede volver a vincular o reescribir manualmente si sigue estas reglas y usa la mente astuta para descubrir qué y cómo curar.
Por ejemplo, la siguiente tabla describe el número de sectores por clúster para diferentes sistemas de archivos, mediante el cual puede encontrar el número de sectores por clúster para su disco. Supongamos que tenía un volumen de aproximadamente 10 GB en su disco y que el sistema operativo que estaba usando era Windows 98.
Ahora, si de alguna manera la información de "Sectores por clúster" del DBR del volumen está dañada. Intentemos averiguar qué sistema de archivos y cuántos sectores por clúster tenía en el volumen de su disco.
Como el sistema operativo de su disco era Windows 98, que solo admite sistemas de archivos FAT, el sistema de archivos de su volumen era FAT. Ahora pensemos en el tamaño del volumen, que era de aproximadamente 10 GB.
Sabemos que la partición de 10 GB no es compatible con FAT16 (consulte la tabla a continuación), por lo tanto, el sistema de archivos del volumen debe ser FAT32.
Ahora intentemos calcular el número de sectores por clúster para el volumen. Como vemos en la tabla, la partición dentro del rango de 8 GB a 16 GB tiene un grupo de 8 sectores.
Por lo tanto, ahora podemos concluir que en el volumen, el sistema de archivos era FAT32 con 8 sectores por clúster. De manera similar, podemos ensamblar la otra información del DBR utilizando otros enfoques lógicos descritos en los capítulos anteriores de este libro.
El siguiente programa ha sido escrito para reescribir la información de los parámetros del disco en DBR de 1.44Mb, disquete de 3½ pulgadas, con 80 pistas, 2 cabezas (lados) y 18 sectores por pista.
/* Programa para reescribir los parámetros de un disquete de 1,44 MB y 3½ pulgadas en su DBR */
# include "dos.h"
# include "stdio.h"
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ; /* OEM ID and Version*/
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Number of Sectors
Per Cluster */
int res_sec ; /* Reserved Sectors */
char fat_copies ; /* Number of FATs */
int root_dir_entry ; /* Number of Root
Directory Entries */
unsigned int no_sects ; /* Number of Total
Sectors */
unsigned char format_id ; /* Media Descriptor
Byte */
int sec_per_fat ; /* Sectors Per FAT */
int sec_per_trk ; /* Sectors Per FAT */
int no_sides ; /* Number of
Sides(Heads) */
int no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned char rest_code[482] ;/* Rest 482 Bytes code
of DBR */
} ;
struct boot b ;
main( )
{
int val ;
val = absread(0, 1, 0, &b); /* Use For Floppy Disk */
if ( val == -1 )
{
printf ( "\n Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
display_info();
getch();
printf("\n Now Recovering BDR of Floppy.....\n");
Recover_with_values();
printf ( "\n Disk Recovered Successfully." ) ;
display_info();
return 0;
}
/* Función para cambiar los parámetros de DBR */
Recover_with_values()
{
int val =0;
/* Jump Code of 3 Bytes For Floppy */
b.code[0] = 0xEB;
b.code[1]= 0x3E;
b.code[2]= 0x90 ;
/* System Id of 8 Bytes */
strcpy(b.system_id, "+05PSIHC");
/* Bytes Per Sector = 512 */
b.bytes_per_sec = 512;
/* Sector per Cluster for 1.44M 3.5" Floppy = 1 */
b.sec_per_clus = 1;
/* Number of Reserved Sectors = 1 */
b.res_sec =1;
/* Number of FAT Copies = 2 */
b.fat_copies =2;
/* Number of Root Directory Entry = 224 */
b.root_dir_entry =224;
/* Number of Sectors on Disk = 2880 */
b.no_sects =2880;
/* Media Descriptor Byte For Floppy = F0 (H) */
b.format_id =0xF0;
/* Sectors Per FAT = 9 */
b.sec_per_fat =9;
/* Sectors Per Track = 18 */
b.sec_per_trk =18;
/* Number of Sides = 2 */
b.no_sides =2;
/* Number of Special Reserved Sectors (or Hidden
Sectors) = 0 */
b.no_sp_res_sect =0;
/* Use For Floppy Disk*/
val = abswrite ( 0, 1, 0, &b ) ;
if ( val == -1 )
{
printf ( "\n Disk Write Error...bad sector\n" ) ;
printf ( " Disk was not Recovered." ) ;
exit ( 1 ) ;
}
return 0;
}
display_info()
{
printf ( "\n Jump Code (Hex) = %X%X%X (H)\n",
b.code[0],b.code[1],b.code[2]);
printf ( " System ID = %s\n",
b.system_id ) ;
printf ( " Bytes per sector = %d\n",
b.bytes_per_sec ) ;
printf ( " Sectors per cluster = %d\n",
b.sec_per_clus ) ;
printf ( " Reserved sectors = %d\n",
b.res_sec ) ;
printf ( " FAT copies = %d\n",
b.fat_copies ) ;
printf ( " Root directory entries = %d\n",
b.root_dir_entry ) ;
printf ( " No. of sectors on disk = %u\n",
b.no_sects ) ;
printf ( " Media Descriptor Byte = %X\n",
b.format_id ) ;
printf ( " Sectors per FAT = %d\n",
b.sec_per_fat ) ;
printf ( " Sectors per track = %d\n",
b.sec_per_trk ) ;
printf ( " No.sides = %d\n",
b.no_sides ) ;
printf ( " No. of reserved sectors = %d\n",
b.no_sp_res_sect ) ;
return 0;
}
Comentarios sobre la codificación:
La estructura de arranque se utiliza para acceder al DBR, para leer y escribir los parámetros del disco. La función display_info(), muestra los distintos parámetros del disco, leyendo desde el DBR. La función Recover_with_values() se usa para modificar y recuperar los parámetros de DBR de Floppy.
Los valores utilizados por la función Recover_with_values(), son para parámetros de 1,44 MB, DBR de disquete de 3 ½ pulgadas. La descripción de estos valores se ha dado en la siguiente tabla:
Página modificada el: 17/01/2022