장 – 13
프로그래밍으로 DBR 읽기 및 수정
DOS 부트 레코드(DBR) / DOS 부트 섹터
DOS 부트 레코드(DBR)/DOS 부트 섹터
파티션 테이블 다음으로 DOS 부트 레코드(DBR) 또는 DOS 부트 섹터라고도 하는 하드 드라이브에서 두 번째로 중요한 정보입니다.
DBR에 대한 자세한 연구는 이 책의 앞부분에서 논의된 "디스크 및 OS에 대한 논리적 접근" 장을 참조하십시오.
각 DOS 파티션의 첫 번째 논리 섹터에는 DOS 부트 레코드(DBR) 또는 DOS 부트 섹터가 포함됩니다. DBR의 역할은 하드 디스크 드라이브에서 컴퓨터의 주 메모리로 운영 체제를 로드하고 로드된 프로그램에 시스템 제어 권한을 부여하는 것입니다.
하드 디스크의 첫 번째 파티션에 대한 DOS 부트 레코드(DBR)는 일반적으로 Absolute Sector 63(디스크 드라이브의 64번째 섹터) 또는 CHS 형식에서 찾을 수 있습니다. C–H–S = 0–1 대부분의 드라이브에 대해 -1입니다.
그러나 이 위치는 드라이브의 SPT(트랙당 섹터)에 따라 다를 수 있습니다. 예를 들어, SPT가 31개만 있는 구형 245MB 드라이브에서 부트 레코드는 32번째 섹터(절대 섹터 31)에 있었습니다.
플로피에 파티션이 없으므로 첫 번째 섹터에 MBR 또는 마스터 파티션 테이블이 없고 대신 첫 번째 섹터에 DBR이 포함됩니다.
DBR은 FDISK 명령을 사용하여 파티션을 나눈 후 DOS의 FORMAT 명령에 의해 생성됩니다. DBR이 있는 섹터는 DOS용 특정 파티션의 논리적 섹터 1이 됩니다. DOS에서 사용하는 섹터 번호는 DBR이 있는 물리적 섹터에서 시작합니다.
DBR에는 마스터 부트 레코드(MBR) 실행 프로그램에 의해 실행되는 작은 프로그램이 포함되어 있습니다. 모든 DOS 파티션에는 시스템을 부팅하는 프로그램 코드가 포함되어 있습니다. 즉, 운영 체제를 로드하지만 해당 파티션만 파티션 테이블 항목에서 활성 파티션으로 지정된 마스터 부트 레코드에 의해 제어됩니다.
DBR이 어떤 식으로든 손상된 경우 부팅 가능한 플로피나 CD에서 시스템을 부팅하면 드라이브에 액세스할 수 있어야 합니다. 하드 디스크는 부팅할 수 없지만(Active 파티션의 DBR이 손상된 경우) 일반적으로 디스크 드라이브의 데이터에 대한 액세스에는 영향을 미치지 않습니다. 부팅 가능한 디스크로 시스템을 부팅한 후 데이터에 액세스할 수 있습니다.
/* 플로피의 부팅 매개변수 표시 */
# 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;
}
이 프로그램을 실행하여 70개 트랙, 양면, 트랙당 18개 섹터 및 섹터당 512바이트를 포함하는 1.44M, 3½인치 플로피 디스크의 DBR을 테스트하면 프로그램의 출력이 다음과 유사하게 표시됩니다.
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
대용량 DBR 읽기
크기가 32MB보다 큰 파티션 볼륨은 32MB 이하의 DBR과 DBR 형식이 다릅니다.
디스크의 대용량을 지원하기 위한 것입니다(자세한 설명은 이 책의 앞부분에서 논의한 "디스크 및 OS에 대한 논리적 접근" 장 참조).
FAT32 볼륨의 DOS 부트 레코드 형식은 다음 표에 나와 있습니다.
다음 프로그램은 크기가 32MB 이상인 대용량 볼륨의 DBR을 읽는 프로그램입니다.
/* 대용량 디스크 볼륨의 부팅 매개변수를 표시하는 프로그램 */
# 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();
}
//////// 10진수에서 2진수로의 변환 함수 \\\\\\\\
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);
/* 반전 및 출력 이진 숫자 */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
대용량의 DBR을 읽기 위해 프로그램을 실행하면 프로그램의 출력은 다음과 같이 표시됩니다.
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)
프로그램의 출력에서 다음 매개변수가 0으로 표시되는 것을 볼 수 있습니다.
- 루트 디렉토리 항목
- 디스크의 섹터 수
- FAT당 섹터 수
이 매개변수는 파티션 볼륨의 크기가 32MB보다 크고 실제 정보가 DBR의 확장 볼륨 정보 블록에 있는 경우 값이 0으로 설정되기 때문에 그렇습니다.
예를 들어, DBR 정보의 초기 부분에서 FAT당 섹터 수가 0이고 DBR의 확장 볼륨 정보 블록에서 FAT당 섹터 수가 11003이며, 이는 이 대용량 볼륨에 대한 실제 값입니다. .
볼륨의 DBR에는 프로그래밍 목적으로 모든 데이터 정보를 연결하는 데 사용할 수 있는 디스크 매개변수에 대한 중요한 정보가 있습니다. 예를 들어 디스크에 있는 다른 파티션 볼륨의 DBR에 액세스하려는 경우 DBR 및 기타 관련 정보로 작성된 섹터 수로 계산할 수 있습니다.
클러스터 방식으로 디스크에 액세스하려는 경우 클러스터당 섹터, FAT당 섹터 및 기타 정보를 사용하여 계산할 수 있습니다.
8.4GB보다 큰 하드 디스크를 사용하는 경우(이 책의 앞부분에서 논의한 "디스크 및 OS에 대한 논리적 접근" 장 참조) 확장을 사용하여 8.4GB를 초과하는 디스크의 모든 DBR에 액세스하십시오. 이전 장에서 제공된 확장된 읽기-쓰기 기능을 참조하십시오.
프로그래밍으로 DBR을 복구하는 방법
몇 가지 까다로운 접근 방식과 논리적 계산을 사용하여 디스크 볼륨의 DBR을 최대 100%까지 복구할 수 있습니다. 이 책의 앞부분인 "디스크와 OS에 대한 논리적 접근" 장에서 파일 시스템의 논리적 접근 방식에 대해 논의했듯이 DBR의 모든 정보는 일정한 제한 또는 규칙 내에서 작성됩니다.
DBR에 기록된 모든 매개변수는 특정한 의미를 가지며 특정한 규칙과 이유에 따라 기록됩니다. 그렇기 때문에 DBR의 정보가 손실된 경우 이 규칙을 따르고 치료 대상과 방법을 찾기 위해 까다로운 마음을 사용하면 수동으로 다시 연결하거나 다시 작성할 수 있습니다.
예를 들어 다음 표에서는 디스크의 클러스터당 섹터 수를 찾을 수 있는 다양한 파일 시스템의 클러스터당 섹터 수를 설명합니다. 디스크에 약 10GB의 볼륨이 있고 사용 중인 운영 체제가 Windows 98이라고 가정하겠습니다.
이제 볼륨의 DBR에 대한 "클러스터당 섹터" 정보가 어떻게 손상되었는지 확인합니다. 디스크 볼륨에 있는 클러스터당 섹터 수와 파일 시스템을 알아보겠습니다.
디스크의 운영 체제는 FAT 파일 시스템만 지원하는 Windows 98이므로 볼륨의 파일 시스템은 FAT입니다. 이제 약 10GB였던 볼륨의 크기를 생각해 보겠습니다.
10GB 파티션은 FAT16에서 지원되지 않으므로(다음 표 참조) 볼륨의 파일 시스템은 FAT32여야 합니다.
이제 볼륨의 클러스터당 섹터 수를 계산해 보겠습니다. 표에서 볼 수 있듯이 8GB ~ 16GB 범위의 파티션에는 8개 섹터의 클러스터가 하나 있습니다.
따라서 이제 볼륨에서 파일 시스템이 클러스터당 8개 섹터가 있는 FAT32라는 결론을 내릴 수 있습니다. 마찬가지로 이 책의 이전 장에서 설명한 다른 논리적 접근 방식을 사용하여 DBR의 다른 정보를 조합할 수 있습니다.
다음 프로그램은 1.44Mb, 3½인치 플로피 디스크의 DBR에 디스크 매개변수 정보를 다시 쓰기 위해 트랙당 80트랙, 2헤드(측면) 및 18섹터로 작성되었습니다.
/* 1.44MB, 3½인치 플로피 디스크의 매개변수를 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;
}
/* 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;
}
코딩에 대한 의견:
구조 부팅은 DBR에 액세스하여 디스크의 매개변수를 읽고 쓰는 데 사용됩니다. display_info() 함수는 DBR에서 읽은 디스크의 다양한 매개변수를 표시합니다. Recover_with_values() 함수는 Floppy의 DBR 매개변수를 수정하고 복구하는 데 사용됩니다.
Recover_with_values() 함수가 사용하는 값은 1.44MB, 3½인치 플로피 디스크의 DBR 매개변수에 대한 것입니다. 이 값에 대한 설명은 다음 표에 나와 있습니다.