장 - 13
프로그래밍을 통한 MBR 읽기 및 수정
DOS 부트 레코드(DBR) / DOS 부트 섹터
파티션 테이블 다음으로 DOS 부트 레코드(DBR) 또는 DOS 부트 섹터라고도 하는 정보는 하드 드라이브에서 두 번째로 중요한 정보입니다.
DBR에 대한 자세한 내용은 이 책의 앞 부분에서 설명한 "디스크와 OS에 대한 논리적 접근 방식" 장을 참조하세요.
각 DOS 파티션의 첫 번째 논리 섹터에는 DOS 부트 레코드(DBR) 또는 DOS 부트 섹터가 포함됩니다. DBR의 역할은 하드 디스크에서 컴퓨터의 주 메모리로 운영 체제를 로드하고 로드된 프로그램으로 시스템 제어권을 넘기는 것입니다.
하드 디스크의 첫 번째 파티션에 대한 DOS 부트 레코드(DBR)는 일반적으로 절대 섹터 63(디스크의 64번째 섹터) 또는 CHS 형태에 위치합니다. 즉, 대부분의 디스크에서 C–H–S = 0–1–1이라고 할 수 있습니다.
그러나 이러한 배열은 드라이브의 SPT(트랙당 섹터)에 따라 달라질 수 있습니다. 예를 들어, SPT가 31개만 있는 오래된 245MB 드라이브에서는 부트 레코드가 섹터 32(절대 섹터 31)에 위치해 있었습니다.
플로피 디스크에는 파티션이 없으므로 첫 번째 섹터에 MBR 또는 마스터 파티션 테이블이 없고, 대신 첫 번째 섹터에 DBR이 들어 있습니다.
DBR은 FDISK 명령으로 파티션을 분할한 후 FORMAT DOS 명령을 통해 생성됩니다. DBR이 있는 섹터는 DOS의 해당 파티션의 논리적 섹터 1이 됩니다. DOS가 사용하는 섹터 번호는 DBR이 위치한 물리적 섹터에서 시작합니다.
DBR에는 마스터 부트 레코드(MBR) 실행 프로그램에 의해 실행되는 작은 프로그램이 들어 있습니다. 모든 DOS 파티션에는 컴퓨터를 부팅하는 프로그램 코드가 들어 있습니다. 운영 체제를 부팅하지만, 이 파티션만이 파티션 테이블 항목에 활성 파티션으로 지정된 마스터 부트 레코드로부터 제어를 받습니다.
DBR이 어떤 식으로든 손상된 경우 부팅 플로피 디스크나 CD에서 시스템을 부팅하면 디스크에 접근할 수 있습니다. 하드 드라이브가 부팅되지 않더라도(활성 파티션의 DBR이 손상된 경우) 일반적으로 드라이브에 있는 데이터에 액세스하는 데 영향을 미치지 않습니다. 부팅 디스크에서 시스템을 부팅한 후 데이터에 액세스할 수 있습니다.
/* 플로피 디스크 부팅 매개변수 표시 */
# <dos.h>를 포함합니다.
# <stdio.h>를 포함합니다.
기초적인( )
{
로딩 구조
{
부호 없는 문자 코드[3] ; /* 전환 코드 */
unsigned char system_id[8] ;/* OEM 이름 및 버전*/
int 초당 바이트; /* 섹터당 바이트 */
심볼 sec_per_clus; /* 클러스터당 섹터 */
int 저장 초; /* 예약된 섹터 */
char fat_copies ; /* FAT의 개수 */
int 루트_디렉토리_항목; /* 루트 번호
디렉토리 항목 */
부호 없는 int no_sects ; /* 섹터 수
논리 볼륨 */
부호 없는 char 형식_ID; /* 미디어 설명자 바이트
*/
int 초당지방; /* FAT의 섹터 */
int 초당트럭당; /* 트랙당 섹터 */
int 측면 없음; /* 헤드의 개수 */
int no_sp_resect ; /* 숨겨진 개수
섹터 */
부호 없는 char rest_code[482] ; /* 나머지 코드 */
} ;
로딩 구조 b ;
기호 temp[4] ;
int val, 드라이브;
val = 0, 1, 0, &b; /* 플로피 디스크에 사용*/
값 == -1인 경우
{
printf("디스크 읽기 오류...불량 섹터\n");
출력(1);
}
clrscr ( ) ;
printf("시스템 식별자 = %s\n",
b.시스템_식별자) ;
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",
b.트럭당초) ;
printf("변의 개수 = %d\n",
b.측면 없음) ;
printf("예약된 섹터 수 = %d\n",
б.sp_resect 없음) ;
0을 반환합니다.
}
코딩 주석:
부팅 구조는 DBR에 액세스하고 디스크 매개변수를 읽고 쓰는 데 사용됩니다. display_info() 함수는 DBR에서 읽어 다양한 디스크 매개변수를 표시합니다. Recover_with_values() 함수는 DBR 플로피 매개변수를 변경하고 복원하는 데 사용됩니다.
Recover_with_values() 함수에서 사용하는 값은 1.44MB, 3½ 인치 DBR 플로피 디스크에 대한 것입니다. 이러한 값에 대한 설명은 아래 표에 나와 있습니다.
