Глава – 13
ЧТЕНИЕ И МОДИФИКАЦИЯ MBR С ПОМОЩЬЮ ПРОГРАММИРОВАНИЯ
Загрузочная запись DOS (DBR) / Загрузочный сектор DOS
После таблицы разделов загрузочная запись DOS (DBR) или иногда называемый загрузочным сектором DOS, является второй по важности информацией на жестком диске.
Подробное изучение DBR см. в главе «Логический подход к дискам и ОС», обсуждавшейся ранее в этой книге.
Первый логический сектор каждого раздела DOS будет содержать DOS Boot Record (DBR) или DOS Boot Sector. Задача DBR — загрузить операционную систему с жесткого диска в основную память компьютера и передать управление системой загруженной программе.
Загрузочная запись DOS (DBR) для первого раздела на жестком диске обычно находится в абсолютном секторе 63 (64-й сектор на диске) или в форме CHS, то есть для большинства дисков мы можем сказать C–H–S = 0–1–1.
Однако это расположение может меняться в зависимости от SPT (Sectors per Track) накопителя. Например, на старом накопителе на 245 МБ, имеющем только 31 SPT, загрузочная запись располагалась в 32-м секторе (абсолютный сектор 31).
Поскольку на дискете нет разделов, в ее первом секторе нет MBR или главной таблицы разделов, вместо этого в самом первом секторе она содержит DBR.
DBR создается командой FORMAT DOS после разбиения на разделы с помощью команды FDISK. Сектор, на котором находится DBR, становится логическим сектором 1 этого конкретного раздела для DOS. Номер сектора, используемый DOS, начинается с физического сектора, на котором находится DBR.
DBR содержит небольшую программу, которая выполняется исполняемой программой Master Boot Record (MBR). Все разделы DOS содержат программный код для загрузки машины, т.е. загрузки операционной системы, но только этот раздел получает управление от Master Boot Record, который указан как активный раздел в записи таблицы разделов.
Если DBR каким-либо образом поврежден, диск должен быть доступен, если вы загрузите систему с загрузочной дискеты или CD. Хотя жесткий диск не является загрузочным (если DBR активного раздела поврежден), в целом это не должно повлиять на доступ к данным на диске. После загрузки системы с загрузочного диска вы можете получить доступ к данным.
/* Отображение параметров загрузки дискеты */
# включить <dos.h>
# включить <stdio.h>
основной( )
{
структура загрузки
{
беззнаковый код символа[3] ; /* Код перехода */
unsigned char system_id[8] ;/* Имя и версия OEM*/
int bytes_per_sec ; /* Байт на сектор */
символ sec_per_clus ; /* Секторов на кластер */
int res_sec ; /* Зарезервированные сектора */
char fat_copies ; /* Количество FAT */
int root_dir_entry ; /* Номер корня
Записи каталога */
unsigned int no_sects ; /* Количество секторов в
Логический том */
unsigned char format_id ; /* Байт дескриптора носителя
*/
int sec_per_fat ; /* Секторов на FAT */
int sec_per_trk ; /* Секторов на дорожку */
int no_sides ; /* Количество голов */
int no_sp_res_sect ; /* Количество скрытых
Сектора */
unsigned char rest_code[482] ; /* Остальная часть кода */
} ;
структура загрузки b ;
символ temp[4] ;
int val, привод ;
val = absread(0, 1, 0, &b) ; /* Использовать для дискеты*/
если ( значение == -1 )
{
printf ( "Ошибка чтения диска...плохой сектор\n" ) ;
выход (1);
}
clrscr ( ) ;
printf ( "Системный идентификатор = %s\n",
б.системный_идентификатор ) ;
printf ( "Байтов на сектор = %d\n",
б.байт_в_сек ) ;
printf ( "Секторов на кластер = %d\n",
б.сек_пер_клус);
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;
}
If you run this program to test the DBR of 1.44M, 3½ Inch Floppy disk having 70 tracks, two sides, 18 sectors per track and 512 bytes in a sector, The Output of the Program will be displayed similar to as follows:
System ID = +1<*uIHC
Bytes per sector = 512
Sectors per cluster = 1
Reserved sectors = 1
FAT copies = 2
Root directory entries = 224
No. of sectors on disk = 2880
Media Descriptor Byte = F0
Sectors per FAT = 9
Sectors per track = 18
No. of sides = 2
No. of reserved sectors = 0
Reading the DBR of Large Volumes
The Partition volumes which are greater than 32MB in size have some different format of DBR than the DBR for less then or Equal to 32MB Volumes.
It is so to provide the support to large Volumes of the disk (For a Detailed description on it, refer the chapter “Logical Approach to Disks and OS”, Discussed earlier in this book).
The format of DOS Boot Record of a FAT32 volume has been given in the following table:

The following program is to read the DBR of large Volumes, which are greater than 32MB in size:
/* Program to display boot parameters of Large Disk Volume */
# 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();
}
//////// Decimal to Binary Conversion Function \\\\\\\\
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);
/* Reverse and output binary digits */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
When the program is run to read the DBR of a large volume, The Output of the Program is displayed as follows:
Jump Instruction Code = EB5890 (H)
OEM name and version = MSWIN4.1
Bytes per sector = 512
Sectors per cluster = 8
Reserved sectors = 32
FAT copies = 2
Root directory entries = 0
No. of sectors on disk = 0
Media Descriptor Byte = F8 (H)
Sectors per FAT = 0
Sectors per track = 63
No. of sides = 255
No. of reserved (Hidden) sectors = 63
=========== For Large (>32MB) Disks ===========
No. of sectors, (if Volume is >32MB) = 11277567
Number of Sectors per FAT = 11003
Root Directory Starting Cluster = 2
File System Information Sector = 1
Sector Number of Backup Boot Sector = 6
Physical Drive Number = 80 (H)
Extended Boot Signature = 29 (H)
32-Bit Binary Volume ID = 110101010001100001110111100101 (B)
Volume Label = SAAYA
FAT name = FAT32
Magic Number = 55AA (H)
In the output of the program we see that the following parameters are shown zero:
- Root Directory Entry
- Number of Sectors on Disk
- Number Sectors Per FAT
These parameters are so because these values are set to zero, if the partition volume is greater then 32MB in size and the actual information is found in the Extended Volume Information Block of the DBR.
For Example, in the initial part of the DBR information, the number of Sectors per FAT is 0 and in the Extended Volume Information Block of DBR the Number of Sectors per FAT is 11003, which is the Actual Value for this large Volume.
The DBR of the Volume has the important information about the disk parameters, which can be used to link the all data information for programming purpose. For Example, if you want to access the DBRs of other Partition volume on the disk, you can calculate it by number of sectors, written in DBR and other related information.
If you want to access the Disk with cluster approach, you can make calculations with the help of Sectors per cluster, sectors per FAT and other information.
If you are using the hard disk larger than 8.4 GB (See the chapter, “Logical Approach to Disks and OS”, Discussed earlier in this book), use extensions to access all the DBR’s of the disk beyond 8.4 GB. Refer the Extended read-write functions, given in the previous chapters
How to Recover DBR with Programming
You can recover the DBR of the disk volume up to 100 percent by using some tricky approach and logical calculations. As we discussed about logical approaches of file systems in the chapter, “Logical Approach to Disks and OS”, earlier in this book, the every information in DBR is written within being some limit or rule.
Every parameter written in the DBR has some Specific meaning and written so by following some specific rule and reason. That is why the information of DBR if lost, can be Re-linked or rewritten manually if you follow these rule and use the tricky mind to find out what and how to cure.
For example, the table given next describes the number of sectors per cluster for different file systems, by using which you can find the number of sectors per cluster for your disk. Let us assume that you had a volume of approximately 10GB in your disk and the operating system which you were using was Windows 98.
Now, if any how the “Sectors per cluster” information of the DBR of the volume is corrupted. Let us try to find out which file system and how many sectors per clusters you had in the volume of your disk.
As the operating system in you disk was windows 98, which supports only FAT file system, therefore the File system of your Volume was FAT. Now let us think about the size of the volume, which was approximately 10GB.
We know that the 10GB Partition is not Supported by FAT16 (See the table given next) therefore the File system of the volume should be FAT32.
Now let us try to calculate the number of sectors per cluster for the volume. As we see in the table that the partition within the range of 8GB to 16GB has one cluster of 8 sectors.

Therefore, now we can conclude that in the volume, The File system was FAT32 with 8 sectors per cluster. Similarly we can assemble the other information of the DBR using other logical approaches described in the previous chapters of this book.
The following program has been written to rewrite the information of disk parameters in DBR of 1.44Mb, 3½ inch floppy disk, with 80 tracks, 2 heads (sides) and 18 sectors per track.
/* Program to Rewrite the parameters of 1.44MB, 3½ inch floppy disk to its 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;
}
/* Function To Change the Parameters of 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 (" Байт дескриптора носителя = %X\n",
б.format_id ) ;
printf ("Секторов на FAT = %d\n",
б.сек_пер_жир ) ;
printf ("Секторов на дорожку = %d\n",
б.сек_пер_трк ) ;
printf ("Количество сторон = %d\n",
б.нет_сторон ) ;
printf ("Количество зарезервированных секторов = %d\n",
б.no_sp_res_sect ) ;
вернуть 0;
}
Комментарии по кодированию:
Структура boot используется для доступа к DBR, для чтения-записи параметров диска. Функция display_info() отображает различные параметры диска, считывая из DBR. Функция Recover_with_values() используется для изменения и восстановления параметров DBR Floppy.
Значения, используемые функцией Recover_with_values(), предназначены для параметров 1,44 МБ, 3 ½ дюймового дискетного диска DBR. Описание этих значений приведено в таблице ниже:
