Capítulo – 13
LEITURA E MODIFICAÇÃO DE MBR COM PROGRAMAÇÃO
Registro de inicialização do DOS (DBR) / Setor de inicialização do DOS
Depois da tabela de partição, o registro de inicialização do DOS (DBR), ou às vezes chamado de setor de inicialização do DOS, é a segunda informação mais importante no disco rígido.
Para uma discussão detalhada sobre DBR, consulte o capítulo "Uma abordagem lógica para discos e sistemas operacionais", discutido anteriormente neste livro.
O primeiro setor lógico de cada partição DOS conterá o DOS Boot Record (DBR) ou DOS Boot Sector. A função do DBR é carregar o sistema operacional do disco rígido para a memória principal do computador e transferir o controle do sistema para o programa carregado.
O DOS Boot Record (DBR) para a primeira partição de um disco rígido geralmente está localizado no setor absoluto 63 (o 64º setor do disco) ou no formato CHS, ou seja, para a maioria dos discos podemos dizer C–H–S = 0–1–1.
No entanto, esse arranjo pode variar dependendo do SPT (Setores por Trilha) da unidade. Por exemplo, em uma unidade antiga de 245 MB que tinha apenas 31 SPTs, o registro de inicialização estava localizado no setor 32 (setor absoluto 31).
Como o disquete não tem partições, ele não tem um MBR ou Tabela de Partição Mestre em seu primeiro setor; em vez disso, ele contém um DBR no primeiro setor.
O DBR é criado pelo comando FORMAT DOS após o particionamento com o comando FDISK. O setor onde o DBR reside se torna o setor lógico 1 dessa partição específica para o DOS. O número do setor usado pelo DOS começa no setor físico onde o DBR está localizado.
O DBR contém um pequeno programa que é executado pelo programa executável Master Boot Record (MBR). Todas as partições DOS contêm o código do programa para inicializar a máquina, ou seja, inicializa o sistema operacional, mas somente esta partição recebe o controle do Master Boot Record, que é especificado como a partição ativa na entrada da tabela de partições.
Se o DBR estiver danificado de alguma forma, o disco poderá ser acessado se você inicializar o sistema a partir de um disquete ou CD de inicialização. Embora o disco rígido não seja inicializável (se o DBR da partição ativa estiver danificado), em geral isso não deve afetar o acesso aos dados na unidade. Após inicializar o sistema a partir do disco de inicialização, você pode acessar os dados.
/* Exibe parâmetros de inicialização do disquete */
# incluir <dos.h>
# incluir <stdio.h>
básico( )
{
estrutura de carga
{
código de caractere sem sinal[3] ; /* Código de transição */
unsigned char system_id[8] ;/* Nome e versão do OEM*/
int bytes_por_seg ; /* Bytes por setor */
símbolo sec_per_clus ; /* Setores por cluster */
int res_sec ; /* Setores reservados */
char fat_copies ; /* Número de FAT */
int entrada_diretório_raiz; /* Número raiz
Entradas de diretório */
int não assinado no_sects; /* Número de setores em
Volume Lógico */
formato char não assinado_id; /* Byte do descritor de mídia
*/
int seg_por_gordura; /* Setores no FAT */
int seg_por_trk ; /* Setores por trilha */
int sem_lados; /* Número de cabeças */
int no_sp_res_sect ; /* Número de ocultos
Setor */
char não assinado rest_code[482] ; /* Resto do código */
} ;
estrutura de carga b ;
símbolo temp[4] ;
int val, unidade;
val = absread(0, 1, 0, &b) ; /* Usar para disquete*/
se ( valor == -1 )
{
printf("Erro ao ler disco...setor defeituoso\n");
saída (1);
}
clrscr();
printf("Identificador do sistema = %s\n",
b.identificador_do_sistema ) ;
printf("Bytes por setor = %d\n",
b.bytes_em_seg ) ;
printf( "Setores por cluster = %d\n",
b.sec_por_classe);
printf("Setores reservados = %d\n",
b.res_sec ) ;
printf("cópias FAT = %d\n",
b.fat_copies ) ;
printf("Entradas do diretório raiz = %d\n",
b.entrada_diretório_raiz ) ;
printf( "Número de setores no disco = %u\n",
b.no_sects ) ;
printf("Byte do descritor de mídia = %X\n",
b.format_id ) ;
printf( "Setores por FAT = %d\n",
b.sec_por_gordura ) ;
printf( "Setores por trilha = %d\n",
b.sec_per_trk ) ;
printf("Número de lados = %d\n",
b.no_sides ) ;
printf( "Número de setores reservados = %d\n",
b.no_sp_res_sect ) ;
retornar 0;
}
Se você executar este programa para testar o DBR de um disquete de 1,44 M, 3½ polegadas, com 70 trilhas, dois lados, 18 setores por trilha e 512 bytes em um setor, a saída do programa será exibida de forma semelhante à seguinte:
ID do sistema = +1<*uIHC
Bytes por setor = 512
Setores por cluster = 1
Setores reservados = 1
Cópias FAT = 2
Entradas do diretório raiz = 224
Nº de setores no disco = 2880
Byte do descritor de mídia = F0
Setores por FAT = 9
Setores por trilha = 18
Nº de lados = 2
Nº de setores reservados = 0
Lendo o DBR de Grandes Volumes
Os volumes de partição com tamanho maior que 32 MB têm um formato de DBR diferente do DBR para volumes menores ou iguais a 32 MB.
É assim para fornecer suporte a grandes volumes de disco (para uma descrição detalhada, consulte o capítulo “Abordagem lógica para discos e sistemas operacionais”, discutido anteriormente neste livro).
O formato do DOS Boot Record de um volume FAT32 é fornecido na tabela a seguir:

O programa a seguir serve para ler o DBR de grandes volumes, maiores que 32 MB:
/* Programa para exibir parâmetros de inicialização de grande volume de disco */
# include "dos.h"
# incluir "stdio.h"
vazio principal()
{
inicialização de estrutura
{
unsigned char code[3] ; /* Código de salto */
unsigned char system_id[8] ; /* Nome e versão do OEM */
int bytes_per_sec ; /* Bytes por setor */
char sec_per_clus ; /* Setores por Cluster*/
unsigned int res_sec ; /* Número de Reservados
Setores */
char fat_copies ; /* Número de FATs */
unsigned int root_dir_entry ;/* Número de Root
Entrada de diretório */
unsigned int no_sects ; /* Número de setores em
Volume lógico (se
O volume é <= 32 MB) */
unsigned char Media_id ; /* Byte do descritor de mídia
*/
unsigned int sec_per_fat ; /* Setor por FAT */
unsigned int sec_per_trk ; /* Setores por trilha */
unsigned int no_sides ; /* Número de cabeças */
unsigned long no_sp_res_sect ; /* Número de Ocultos
Setores */
unsigned long long_sec_num ; /* Total de setores em
Volume Lógico
(Tamanho >32MB) */
unsigned long num_sec_per_FAT; /* Setores por FAT */
unsigned int binary_flags; /* Sinalizadores binários */
unsigned char version_of_FAT1; /* Primeiro Byte de FAT
Versão */
unsigned char version_of_FAT2; /* Segundo Byte de FAT
Versão */
root_dir_start_cluster longo não assinado;
/* Diretório raiz
Cluster inicial
Número */
int não assinado sec_num_of_file_sys;
/* Número do setor de
Sistema de arquivos
Setor de Informação
*/
int não assinado seg_num_do_backup_boot_sec;
/* Número do setor de
Setor de inicialização de backup
*/
unsigned char reservado[12]; /* Reservado */
unsigned char número_da_unidade_lógica;
/* Unidade física
Número de Lógicos
Volume */
unsigned char unused_byte; /* Byte não utilizado */
char não assinado hex_extd_boot_signature;
/* Inicialização estendida
Assinatura(29H) */
unsigned long binary_volume_ID;/* ID do volume binário */
unsigned char volume_label[11];/* Rótulo do volume */
unsigned char FAT_name[8]; /* Nome FAT */
unsigned char rest_code[420] ; /* Resto 420 Bytes de
O DBR */
unsigned char magic_number[2]; /* Número mágico */
} ;
estrutura de inicialização b;
char temp[4] ;
int val, unidade,i;
val = biosdisk(2, 0x80, 1,0,1,1, &b) ;
/* Para o primeiro disco rígido */
se ( val == -1 )
{
printf("Erro de leitura de disco...setor defeituoso\n");
saída ( 1 ) ;
}
clrscr();
printf( " Código de Instrução de Salto = ");
para(i=0;i<=2;i++)
{
printf("%X",b.código[i]);
}
printf("(H)\n ");
printf("Nome e versão do OEM = %s\n ",
b.id_do_sistema ) ;
printf("Bytes por setor = %u\n ",
b.bytes_por_seg ) ;
printf( "Setores por cluster = %u\n ",
b.sec_per_clus );
printf("Setores reservados = %u\n ",
b.res_sec ) ;
printf("cópias FAT = %d\n ",
b.fat_copies ) ;
printf("Entradas do diretório raiz = %u\n",
b.entrada_diretório_raiz ) ;
printf("Número de setores no disco = %u\n ",
b.no_sects ) ;
printf("Byte do descritor de mídia = %X(H)\n",
b.Media_id ) ;
printf("Setores por FAT = %u\n ",
b.sec_por_gordura ) ;
printf( "Setores por trilha = %u\n ",
b.sec_per_trk ) ;
printf("Número de lados = %u\n ",
b.no_sides ) ;
printf("Número de setores reservados (ocultos)= %lu\n ",
b.no_sp_res_sect ) ;
printf("========== Para discos grandes (> 32 MB) ========\n");
printf("Número de setores,(se o volume for >32MB) = %lu\n ",
b.long_sec_num) ;
printf ( “Número de setores por FAT = %lu\n “,
b.num_sec_per_FAT );
printf("Diretório raiz iniciando cluster = %lu\n ",
b.root_dir_start_cluster);
printf("Setor de Informações do Sistema de Arquivos = %u\n ",
b.sec_num_do_sistema_de_arquivos);
printf("Número do setor de inicialização de backup = %u\n",
b.sec_num_de_backup_boot_sec);
printf("Número da unidade física = %X(H)\n",
b.número_da_unidade_lógica);
printf("Assinatura de inicialização estendida = %X(H)\n",
b.hex_extd_boot_signature);
printf( "ID do volume binário de 32 bits = ");
Decimal_para_binário (b.binary_volume_ID,32);
printf("(B)\n");
printf("Rótulo do volume = ");
para(i=0;i<=10;i++)
{
printf("%c",b.volume_label[i]);
}
printf("\n nome FAT = ");
para(i=0;i<=7;i++)
{
printf("%c",b.FAT_name[i]);
}
printf("\n");
printf("Número Mágico = %X%X(H)",
b.número_mágico[0],b.número_mágico[1]);
obter();
}
//////// Função de conversão decimal para binário \\\\\\\\
Decimal_to_Binary(entrada longa sem sinal)
{
i longo sem sinal;
contagem int = 0;
int binário [32]; /* 32 bits MAX somente 32
elementos total */
fazer
{
i = input%2; /* MOD 2 para obter 1 ou 0*/
binary[count] = i; /* Carregar elementos no
Matriz binária */
input = input/2; /* Dividir a entrada por 2 para
decremento via binário */
count++; /* Contar elementos howy
são necessários */
}enquanto (entrada > 0);
/* Reverter e emitir dígitos binários */
fazer
{
printf ("%d", binário[contagem - 1]);
contar--;
} enquanto (contagem > 0);
retornar 0;
}
Quando o programa é executado para ler o DBR de um grande volume, a saída do programa é exibida da seguinte forma:
Código de instrução de salto = EB5890 (H)
Nome e versão do OEM = MSWIN4.1
Bytes por setor = 512
Setores por cluster = 8
Setores reservados = 32
Cópias FAT = 2
Entradas do diretório raiz = 0
Nº de setores no disco = 0
Byte do descritor de mídia = F8 (H)
Setores por FAT = 0
Setores por trilha = 63
Nº de lados = 255
Nº de setores reservados (ocultos) = 63
=========== Para discos grandes (> 32 MB) =========== Nº de setores (se o volume for > 32 MB) = 11277567 Número de setores por FAT = 11003 Cluster inicial do diretório raiz = 2 Setor de informações do sistema de arquivos = 1 Número do setor do setor de inicialização de backup = 6 Número da unidade física = 80 (H) Assinatura de inicialização estendida = 29 (H) ID de volume binário de 32 bits = 110101010001100001110111100101 (B) Rótulo de volume = SAAYA Nome FAT = FAT32 Número mágico = 55AA (H)
Na saída do programa vemos que os seguintes parâmetros são mostrados como zero:
- Entrada do diretório raiz
- Número de setores no disco
- Número de setores por FAT
Esses parâmetros existem porque esses valores são definidos como zero se o volume da partição for maior que 32 MB e as informações reais forem encontradas no Bloco de Informações de Volume Estendido do DBR.
Por exemplo, na parte inicial das informações do DBR, o número de setores por FAT é 0 e no Bloco de informações de volume estendido do DBR o número de setores por FAT é 11003, que é o valor real para esse grande volume.
O DBR do Volume tem informações importantes sobre os parâmetros do disco, que podem ser usados para vincular todas as informações de dados para fins de programação. Por exemplo, se você quiser acessar os DBRs de outro volume de partição no disco, você pode calculá-lo pelo número de setores, escritos em DBR e outras informações relacionadas.
Se você quiser acessar a abordagem de disco com cluster, poderá fazer cálculos com a ajuda de setores por cluster, setores por FAT e outras informações.
Se você estiver usando um disco rígido maior que 8,4 GB (veja o capítulo, “Abordagem Lógica para Discos e SO”, discutido anteriormente neste livro), use extensões para acessar todos os DBRs do disco além de 8,4 GB. Consulte as funções de leitura e gravação estendidas, fornecidas nos capítulos anteriores
Como recuperar DBR com programação
Você pode recuperar o DBR do volume do disco em até 100 por cento usando alguma abordagem complicada e cálculos lógicos. Como discutimos sobre abordagens lógicas de sistemas de arquivos no capítulo, “Abordagem Lógica para Discos e SO”, anteriormente neste livro, todas as informações no DBR são escritas dentro de algum limite ou regra.
Cada parâmetro escrito no DBR tem algum significado específico e é escrito assim seguindo alguma regra e razão específica. É por isso que as informações do DBR, se perdidas, podem ser Re-linked ou reescritas manualmente se você seguir essas regras e usar a mente complicada para descobrir o que e como curar.
Por exemplo, a tabela dada a seguir descreve o número de setores por cluster para diferentes sistemas de arquivos, usando a qual você pode encontrar o número de setores por cluster para seu disco. Vamos supor que você tinha um volume de aproximadamente 10 GB em seu disco e o sistema operacional que você estava usando era o Windows 98.
Agora, se de alguma forma as informações de “Setores por cluster” do DBR do volume estiverem corrompidas. Vamos tentar descobrir qual sistema de arquivos e quantos setores por cluster você tinha no volume do seu disco.
Como o sistema operacional no seu disco era o Windows 98, que suporta apenas o sistema de arquivos FAT, portanto o sistema de arquivos do seu volume era FAT. Agora, vamos pensar no tamanho do volume, que era de aproximadamente 10 GB.
Sabemos que a partição de 10 GB não é suportada pelo FAT16 (veja a tabela a seguir), portanto o sistema de arquivos do volume deve ser FAT32.
Agora, vamos tentar calcular o número de setores por cluster para o volume. Como vemos na tabela, a partição dentro do intervalo de 8 GB a 16 GB tem um cluster de 8 setores.

Portanto, agora podemos concluir que no volume, o File system era FAT32 com 8 setores por cluster. Similarmente, podemos montar as outras informações do DBR usando outras abordagens lógicas descritas nos capítulos anteriores deste livro.
O programa a seguir foi escrito para reescrever as informações dos parâmetros do disco em DBR de 1,44 Mb, disquete de 3½ polegadas, com 80 trilhas, 2 cabeças (lados) e 18 setores por trilha.
/* Programa para reescrever os parâmetros de um disquete de 1,44 MB e 3½ polegadas em seu DBR */
# include "dos.h"
# incluir "stdio.h"
inicialização de estrutura
{
unsigned char code[3] ; /* Código de salto */
unsigned char system_id[8] ; /* ID e versão do OEM*/
int bytes_per_sec ; /* Bytes por setor */
char sec_per_clus ; /* Número de setores
Por cluster */
int res_sec ; /* Setores Reservados */
char fat_copies ; /* Número de FATs */
int root_dir_entry ; /* Número de Root
Entradas de diretório */
unsigned int no_sects ; /* Número de Total
Setores */
unsigned char format_id ; /* Descritor de mídia
Byte */
int sec_per_fat ; /* Setores por FAT */
int sec_per_trk ; /* Setores por FAT */
int no_sides ; /* Número de
Lados (Cabeças) */
int no_sp_res_sect ; /* Número de Ocultos
Setores */
unsigned char rest_code[482] ;/* Resto 482 Bytes código
de DBR */
} ;
estrutura de inicialização b;
principal( )
{
com uma dica;
val = absread(0, 1, 0, &b); /* Usar para disquete */
se ( val == -1 )
{
printf("\nErro de leitura de disco...setor defeituoso\n");
saída ( 1 ) ;
}
clrscr();
exibir_informações();
obter();
printf("\n Recuperando BDR do disquete.....\n");
Recuperar_com_valores();
printf("\n Disco recuperado com sucesso." ) ;
exibir_informações();
retornar 0;
}
/* Função para alterar os parâmetros do DBR */
Recuperar_com_valores()
{
valor int =0;
/* Código de salto de 3 bytes para disquete */
b.código[0] = 0xEB;
b.código[1]= 0x3E;
b.código[2]= 0x90 ;
/* Id do sistema de 8 bytes */
strcpy(b.system_id, "+05PSIHC");
/* Bytes por setor = 512 */
b.bytes_por_seg = 512;
/* Setor por cluster para disquete de 1,44 M de 3,5 pol. = 1 */
b.sec_por_clus = 1;
/* Número de Setores Reservados = 1 */
b.res_sec =1;
/* Número de cópias FAT = 2 */
b.fat_copies =2;
/* Número de entradas do diretório raiz = 224 */
b.entrada_dir_raiz =224;
/* Número de setores no disco = 2880 */
b.no_sects =2880;
/* Byte do descritor de mídia para disquete = F0 (H) */
b.format_id =0xF0;
/* Setores por FAT = 9 */
b.sec_por_gordura =9;
/* Setores por trilha = 18 */
b.sec_por_trk =18;
/* Número de lados = 2 */
b.sem_lados =2;
/* Número de Setores Reservados Especiais (ou Ocultos
Setores) = 0 */
b.no_sp_res_sect =0;
/* Usar para disquete*/
val = abswrite(0, 1, 0, &b);
se ( val == -1 )
{
printf("\nErro de gravação de disco...setor defeituoso\n");
printf( "O disco não foi recuperado." ) ;
saída ( 1 ) ;
}
retornar 0;
}
exibir_info()
{
printf("\n Código de Salto (Hex) = %X%X%X (H)\n",
b.código[0],b.código[1],b.código[2]);
printf("ID do sistema = %s\n",
b.id_do_sistema ) ;
printf( "Bytes por setor = %d\n",
b.bytes_por_seg ) ;
printf( " Setores por cluster = %d\n",
b.sec_per_clus );
printf( " Setores reservados = %d\n",
b.res_sec ) ;
printf( " cópias FAT = %d\n",
b.fat_copies ) ;
printf("Entradas do diretório raiz = %d\n",
b.entrada_diretório_raiz ) ;
printf( "Número de setores no disco = %u\n",
b.no_sects ) ;
printf("Byte do descritor de mídia = %X\n",
b.format_id ) ;
printf("Setores em FAT = %d\n",
b.sec_por_gordura ) ;
printf("Setores por trilha = %d\n",
b.sec_per_trk ) ;
printf("Número de lados = %d\n",
b.no_sides) ;
printf("Número de setores reservados = %d\n",
б.no_sp_res_sect ) ;
retornar 0;
}
Comentários de codificação:
A estrutura de inicialização é usada para acessar o DBR, para ler e gravar parâmetros de disco. A função display_info() exibe vários parâmetros de disco lendo o DBR. A função Recover_with_values() é usada para alterar e restaurar parâmetros do DBR Floppy.
Os valores usados pela função Recover_with_values() são para um disquete DBR de 1,44 MB e 3 ½ polegadas. Uma descrição desses valores é dada na tabela abaixo:
