장 – 11
백업 만들기
백업을 하는 이유?
“예방이 항상 치료보다 낫다” 백업을 만드는 것은 디스크 충돌이나 다른 유형의 데이터 손실을 극복하는 데 도움이 될 수 있는 데이터 재해 예방의 중요한 부분이기도 합니다. 이 장에서는 이전에 만든 백업을 통해서만 심각한 디스크 충돌이 발생한 후에도 데이터를 복구할 수 있는 방법에 대해 설명합니다.
이전에 저장된 백업에 의해 수행되는 복구는 거의 항상 최대 100%이지만 특정 경우에는 여러 유형의 디스크 충돌로 인해 복구 결과가 달라질 수 있습니다.
백업을 사용하여 데이터를 복구하는 것은 매우 쉽고 빠르고 안정적이며 최상의 결과를 얻을 수 있는 반면 백업 없이 데이터를 복구하는 것은 어렵고 복잡하며 많은 시간이 소요될 수 있습니다. 여러 경우에 100% 데이터를 얻지 못합니다.
백업 시기 및 대상
디스크에는 한 번 또는 다른 시간 간격으로 백업해야 하는 여러 영역이 있습니다. 다음 표는 완전한 백업 조치에 대한 아이디어를 제공하고 백업 시기와 대상을 찾는 데 도움이 됩니다.
What to Backup |
When to be Backed up |
Backup of MBR |
Once after FDISK. The MBR is Created By the FDISK command of DOS. You can take backup of MBR After FDISK, however even after the FORMAT of partitions created by FDISK, The MBR remains Unchanged. |
Backup of DBR |
Back up the DBRs for each logical drive once, after FORMAT. |
Backup of FAT and Directory entries. |
FAT and Directory Entries are changed every time when you create of delete files or directories. Therefore it is recommended that you should take backup daily. |
Backup of User Data |
Should be taken regularly. This type of backup causes the disk imaging to take place. However it is time taking yet most of the companies which have very sensitive data in their disks like to spend their time on disk imaging because by doing this they can backup all of the information described above. |
이 외에도 시스템용 비상 부팅 플로피를 만들어야 합니다. 하드 디스크의 데이터에 어떤 유형의 재해가 있는 경우 이 플로피를 사용하여 시스템을 부팅하고 디스크의 오류를 분석할 수 있습니다.
MBR(마스터 부트 레코드) 백업 및 사용
마스터 부트 레코드(MBR) 또는 마스터 파티션 테이블(MPT)이라고도 하는 이 파일에는 하드 디스크 드라이브에서 활성(또는 부팅 가능한) 파티션을 로드하고 시작하는 작은 프로그램이 포함되어 있습니다. 마스터 부트 레코드에는 4개의 기본 파티션에 대한 정보가 모두 포함되어 있습니다.
MBR에 대한 자세한 연구는 이 책의 앞부분에서 논의된 “디스크 및 OS에 대한 논리적 접근” 장을 참조하십시오.
MBR은 절대 섹터 0에 있거나 실린더 0, 헤드 0 및 섹터 1에 있다고 말할 수 있습니다. DOS의 FDISK.EXE 명령을 실행하여 하드 디스크 드라이브에 생성됩니다.
MBR을 백업해야 하는 이유:
MBR을 사용하면 시스템이 시작될 때 활성 파티션의 부트 섹터가 제어를 받을 수 있습니다.
POST(Power-On Self Test) 후 BIOS는 하드 디스크에서 메모리로 MBR(마스터 부트 레코드)을 로드한 다음 실행합니다. MBR은 먼저 하드 디스크에서 활성 파티션을 확인한 다음 DOS 부트 레코드(DBR)를 메모리에 로드하고 운영 체제 부트 코드로 제어를 넘긴 다음 운영 체제 부트 레코드 코드가 나머지 운영 체제를 로드합니다. 메모리.
디스크의 MBR이 손상되면 하드 디스크가 거의 죽은 상태이며 시스템을 완전히 부팅하거나 운영 체제를 실행할 수 없다고 말할 수 있습니다. 이러한 상태에서는 하드 디스크에 저장된 모든 데이터에 액세스할 수 없게 됩니다. 일반적으로 오류 메시지는 다음과 같이 표시됩니다.
“잘못된 파티션 테이블” “운영 체제 로드 중 오류 발생” “운영 체제가 없습니다."
MBR 백업으로 무엇을 복구할 수 있습니까?
MBR 백업은 위의 오류 메시지를 제거하는 데 도움이 될 수 있습니다. 백업을 통해 다음 문제를 수정할 수 있습니다.
- 손상된 IPL(초기 프로그램 로더)로 인한 운영 체제 로드 중 오류
- 기본 파티션 손실
- 손상된 파티션 정보
- 잘못된 매직 번호
MBR 백업을 위한 프로그램 작성:
/* MBR 백업 프로그램 */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo; /* Structure to Hold the
information of disk Parameters */
int result;
int count=0;
char filename[80]; /* Stores the File name given by
User */
static char dbuf[512]; /* Data Buffer of 512 Bytes */
FILE *fp;
dinfo.drive = 0x80; /* drive number for First Hard
Disk */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
printf("\n Enter The Filename and path to store the
Backup of MBR \n ");
gets(filename);
// 파일을 열어 MBR 백업 저장 \\
if((fp=fopen(filename,"wb"))==NULL)
{
printf("Could not Create File, Press any key to
Exit...");
getch();
exit(0);
}
printf("Attempting to read from Hard disk drive :\n");
//// 지정된 디스크 섹터 읽기 \\\\
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
printf("Disk read from hard disk drive :
successful.\n");
/// 파일에 512바이트의 MBR 쓰기 \\\\
while(count<512)
{
fprintf(fp,"%c",dbuf[count] & 0xff );
count++;
}
fclose(fp);
}
else
printf("Cannot read Hard Disk drive, status = 0x%02x\n", result);
return 0;
}
프로그램 코딩에 대한 의견:
앞서 주어진 프로그램 코딩에서 기본적으로 우리는 다음 작업을 단계별로 진행하고 있습니다.
- dinfo는 _bios_disk 함수가 수행하는 작업에 필요한 매개변수 정보가 포함된 diskinfo_t 구조를 가리킵니다.
- 디스크의 첫 번째 섹터를 읽고 싶기 때문에 섹터의 위치는 다음과 같습니다.
Parameter |
What it means |
dinfo.drive = 0x80 |
It indicates the Physical drive 80H that is the first Hard disk drive. |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
>Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- 사용자가 지정한 파일 이름과 경로의 파일 스트림을 열어 정확한 512바이트의 MBR 백업을 저장합니다. 파일 이름과 경로는 문자 배열 파일 이름에 저장됩니다.
- _bios_disk(_DISK_READ, &dinfo)는 dinfo에서 지정한 하드 디스크(80H)의 첫 번째 섹터를 읽습니다.
- 반환된 상태는 성공적인 작업에 대한 메시지를 표시하거나 오류가 발생한 경우 화면에 오류 메시지를 표시하는 데 사용되는 결과에 저장됩니다.
백업에서 MBR을 복원하는 프로그램:
어떤 식으로든 MBR이 손상된 경우 다음에 제공되는 프로그램은 MBR Back을 복원하는 데 도움이 됩니다.
이 프로그램에 대한 잘못된 사용 또는 지식 부족으로 인해 하드 디스크의 데이터 정보가 손상될 수 있으며 전체 데이터에 액세스할 수 없게 될 수 있음을 항상 염두에 두어야 합니다. 당신은 당신이 무엇을 할 것인지 확신해야 합니다. 그렇지 않으면 문제가 더 복잡해질 수 있습니다.
백업에서 MBR을 복원하는 프로그램:
프로그램의 코딩은 다음과 같습니다.
/* 백업 파일에서 MBR 백업을 복원하는 프로그램 */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
int result;
int count=0;
char filename[80]; /* Stores the File name given
by User */
static char dbuf[512]; /* Data Buffer of 512 Bytes
*/
FILE *fp;
/* MBR 백업 파일 경로에 대한 사용자 입력 가져오기 */
printf("\n Enter The Filename and path of Backup File of
MBR \n ");
gets(filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("Could not open Backup File, Press any key
to Exit...");
getch();
exit(1);
}
/* MBR 데이터는 정확히 512바이트여야 합니다. */
while(count<512)
{
fscanf(fp,"%c",&dbuf[count]);
count++;
}
fclose(fp);
printf("Attempting to Write to Hard disk drive :\n");
dinfo.drive = 0x80; /* drive number for First
Hard Disk */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result = _bios_disk(_DISK_WRITE, &dinfo);
if ((result & 0xff00) == 0)
{
printf("Restoring the Backup of MBR to The Disk
Sector: successful.\n");
}
else
printf("Cannot Write on Hard Disk drive, status =
0x%02x\n", result);
return 0;
}
프로그램 코딩에 대한 의견:
위에 주어진 프로그램 코딩에서 기본적으로 다음 작업을 단계별로 진행합니다.
- dinfo는 _bios_disk 함수가 수행하는 작업에 필요한 매개변수 정보가 포함된 diskinfo_t 구조를 가리킵니다.
- 디스크의 첫 번째 섹터에 쓰기를 원하므로 섹터의 위치는 다음과 같습니다.
Parameter |
What it means |
dinfo.drive = 0x80 |
It indicates the Physical drive 80H that is the first Hard disk drive. |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- 사용자가 지정한 MBR 백업의 파일 이름과 경로는 문자 배열 파일 이름에 저장됩니다. MBR 정보는 정확히 512바이트여야 합니다.
- _bios_disk(_DISK_WRITE, &dinfo)는 dinfo로 지정된 하드 디스크(80H)의 첫 번째 섹터에 데이터를 씁니다.
- 반환된 상태는 성공적인 작업에 대한 메시지를 표시하거나 오류가 발생한 경우 화면에 오류 메시지를 표시하는 데 사용되는 결과에 저장됩니다.
DBR(DOS 부트 레코드) 백업 및 사용
파티션 테이블 다음으로 DOS 부트 레코드(DBR) 또는 DOS 부트 섹터라고도 하는 하드 드라이브에서 두 번째로 중요한 정보입니다.
DBR에 대한 자세한 연구는 이 책의 앞부분에서 논의된 “디스크 및 OS에 대한 논리적 접근” 장을 참조하십시오.
각 DOS 파티션의 첫 번째 논리 섹터에는 DOS 부트 레코드(DBR) 또는 DOS 부트 섹터가 포함됩니다. DBR의 역할은 하드 디스크 드라이브에서 컴퓨터의 주 메모리로 운영 체제를 로드하고 로드된 프로그램에 시스템 제어를 제공하는 것입니다.
하드 디스크의 첫 번째 파티션에 대한 DOS 부트 레코드(DBR)는 일반적으로 Absolute Sector 63(디스크 드라이브의 64번째 섹터) 또는 CHS 형식에서 찾을 수 있습니다. C–H–S = 0–1&ndash ;1 대부분의 드라이브에 대해.
그러나 이 위치는 드라이브의 SPT(트랙당 섹터)에 따라 다를 수 있습니다. 예를 들어, SPT가 31개만 있는 구형 245MB 드라이브에서 부트 레코드는 32번째 섹터(절대 섹터 31)에 있었습니다.
DBR은 FDISK 명령을 사용하여 파티션을 나눈 후 DOS의 FORMAT 명령에 의해 생성됩니다. DBR이 있는 섹터는 DOS용 특정 파티션의 논리적 섹터 1이 됩니다. DOS에서 사용하는 섹터 번호는 DBR이 있는 물리적 섹터에서 시작합니다.
DBR에는 MBR(Master Boot Record) 실행 프로그램에 의해 실행되는 작은 프로그램이 포함되어 있습니다. 모든 DOS 파티션에는 시스템을 부팅하는 프로그램 코드가 포함되어 있습니다. 즉, 운영 체제를 로드하지만 해당 파티션만 파티션 테이블 항목에서 활성 파티션으로 지정된 마스터 부트 레코드에 의해 제어됩니다.
DBR을 백업해야 하는 이유:
DBR에는 디스크 구조에 대한 몇 가지 중요한 정보가 포함되어 있습니다. 이 정보는 다음과 같이 모든 파티션의 첫 번째 섹터에 있습니다.
- 점프 코드 + NOP
- OEM 이름 및 버전
- 섹터당 바이트 수
- 클러스터당 섹터
- 예약 부문
- FAT 사본 수
- 최대 루트 디렉토리 항목(FAT32에는 사용할 수 없음)
- 32MB보다 작은 파티션의 섹터 수(따라서 FAT32에서는 사용할 수 없음)
- 미디어 설명자(하드 디스크의 경우 F8H)
- FAT당 섹터(이전 FAT 시스템에서는 FAT32에서 사용할 수 없음)
- 트랙당 섹터
- 헤드 수
- 파티션의 숨겨진 섹터 수
- 파티션된 섹터 수
- FAT당 섹터 수
- FAT 정보 설명자 플래그
- FAT32 드라이브 버전
- 루트 디렉토리 시작의 클러스터 번호
- 파일 시스템 정보 섹터의 섹터 번호
- 백업 부트 섹터의 섹터 번호
- 예약됨
- 파티션의 논리 드라이브 번호
- 확장 서명(29H)
- 파티션의 일련 번호
- 파티션의 볼륨 이름
- FAT 이름
- 실행 코드
- 실행 마커 또는 매직 넘버(AAH 55H)
일반적으로 다음과 같은 오류 메시지가 화면에 표시됩니다.
“디스크 부팅 실패”
“비시스템 디스크 또는 디스크 오류”
“잘못된 시스템 디스크 또는 디스크 I/O 오류”
“디스크를 교체한 다음 아무 키나 누르십시오.”
DBR 백업으로 무엇을 복구할 수 있나요?
DBR을 백업하면 위의 오류 메시지를 제거하는 데 도움이 될 수 있습니다. 이러한 오류 메시지는 사용자가 플로피 드라이브에 위에서 언급한 프로그램이 포함된 부팅 디스크를 넣고 키를 누를 때까지 화면에 표시됩니다.
드라이브는 부팅 가능한 플로피나 CD에서 시스템을 부팅하는 경우 액세스할 수 있어야 합니다. 하드 디스크는 부팅할 수 없지만 일반적으로 디스크 드라이브의 데이터에 대한 액세스에는 영향을 미치지 않습니다. 부팅 가능한 디스크로 시스템을 부팅한 후 데이터에 액세스할 수 있습니다.
DBR의 백업을 복원하면 위에서 언급한 것처럼 발생하는 문제를 극복할 수 있습니다.
DBR 백업 만들기 및 복원 프로그램:
DBR 백업 및 복원 프로그램은 MBR 백업 및 복원 프로그램과 거의 유사합니다.
예를 들어 디스크의 첫 번째 논리 드라이브의 DBR을 백업하기 위한 프로그램을 작성하고 다시 복원하려는 경우 dinfo 구조에서 지정한 매개변수는 다음과 같이 변경됩니다.
Parameter |
What it means |
dinfo.drive = 0x80 |
It indicates the Physical drive 80H that is the first Hard disk drive> |
dinfo.head = 1 |
It points to head number 1 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
여기서 우리는 읽기/쓰기 섹터의 위치만 변경된 것을 볼 수 있습니다. 여기서 C-H-S는 첫 번째 논리 드라이브의 DBR이 여기에 저장되므로 0-1-1로 지정됩니다.
완전한 디스크 이미징
이 유형의 백업은 오늘날 점점 더 대중화되고 있으며 시스템에 매우 민감한 데이터가 있는 조직에서 가장 선호합니다. 그들은 데이터 손실의 단 1퍼센트도 감수할 수 없습니다.
이러한 조직은 정기적으로 전체 디스크 이미지로 백업을 수행합니다. 시간이 좀 걸리긴 하지만 놓치는 것이 없다는 확신을 줍니다. 인기가 높아짐에 따라 프로그래머는 이미징 프로세스에 걸리는 시간을 최소화하기 위해 디스크 이미징 소프트웨어를 점점 더 빠르게 만들기 위해 최선을 다했습니다.
디스크 이미징은 좋은 아이디어입니다. 몇십 분만 투자하면 주머니에 모든 것을 백업할 수 있다는 마음의 위안을 얻을 수 있기 때문입니다. MBR, BDR, FAT, Root Directories와 같은 모든 요소는 그대로 대상 디스크에 복사됩니다.
디스크 이미징에 필요한 것은 중요한 데이터가 있는 원본 하드 디스크와 동일한(또는 거의 동일한) 대상 하드 디스크입니다. 대상 디스크가 원본 디스크보다 작아서는 안 된다는 점을 항상 염두에 두어야 합니다.
전체 이미지를 촬영한 후 디스크 이미지를 촬영한 대상 디스크로 시스템을 부팅하면 일반적으로 모든 데이터를 있는 그대로 가져옵니다.
완전한 디스크 이미징을 위한 프로그램 작성
디스크 이미징을 위한 프로그램은 다음과 같습니다. 프로그램은 INT 13H 확장을 사용하므로 대용량 디스크도 지원할 수 있습니다.
프로그램은 첫 번째 물리적 하드 디스크 드라이브(0x80)의 이미지를 두 번째 물리적 하드 디스크 드라이브(0x81)로 만들기 때문에 백업 이미지를 만들기 전에 대상 디스크(0x81)의 모든 데이터가 섹터 패턴별로 소스 디스크(0x80)의 데이터를 덮어씁니다.
프로그램 코딩은 다음과 같습니다.
/* 첫 번째 하드 디스크(0x80)의 이미지를 두 번째 하드 디스크(0x81)로 만드는 프로그램 */
#include<stdio.h>
#include<dos.h>
#include<conio.h>
/* INT 13H 확장, 기능 번호 0x48을 사용하는 getdrivegeometry 기능에서 사용할 구조입니다. */
struct geometry
{
unsigned int size ; /* (call) size of Buffer */
unsigned int flags ; /* Information Flags */
unsigned long cyl ; /* Number of Physical
Cylinders on Drive */
unsigned long heads ;/* Number of Physical
Heads on Drive */
unsigned long spt ; /* Number of Physical
Sectors Per Track */
unsigned long sectors[2] ; /* Total Number of
Sectors on Drive */
unsigned int bps ; /* Bytes Per Sector */
} ;
/* 디스크 주소 패킷 형식의 구조, 기능, readabsolutesectors 및 writeabsolutesectors에서 사용 */
struct diskaddrpacket
{
char packetsize ; /* Size of Packet, generally 10H */
char reserved ; /* Reserved (0) */
int blockcount ; /* Number of Blocks to Transfer */
char far *bufferaddress ; /* address to Transfer
Buffer */
unsigned long blocknumber[2] ; /* Starting Absolute
Block Number */
} ;
///// 드라이브 매개변수를 가져오는 함수 \\\\\
unsigned long getdrivegeometry (int drive)
{
union REGS i, o ;
struct SREGS s ;
struct geometry g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
i.h.ah = 0x48 ; /* Function Number 0x48 of INT 13H
Extensions See the Comments
Below */
i.h.dl = drive; /* Drive Number */
i.x.si = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* 세그먼트 레지스터 값을 사용하여 INT 13H 확장의 지정된 기능 번호를 호출합니다. */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Head = %lu, Sectors Per Track = %lu, Cylinder =
%lu\n", g.heads, g.spt, g.cyl);
/* 드라이브 기하학 기능 가져오기가 실패하면 오류 메시지를 표시하고 종료 */
if(g.spt==0)
{
printf("\n Get Drive Geometry Function Fails....");
printf("\n Extensions Not Supported, Press any Key to
Exit...");
getch();
exit(1);
}
return *g.sectors; /* Return The Number of Sectors
on Drive */
}
////// 메인 시작 \\\\\\
void main()
{
unsigned long loop=0, Sectors_in_HDD1=0, Sectors_in_HDD2=0;
unsigned char buffer[61440]; /* Data buffer of 61440
Bytes to Read/Write 120 Sectors of 512 Bytes at a time to save time. */
char choice;
clrscr();
/* 총수인 경우 연결된 하드 디스크 중 오류 메시지 표시 및 종료가 2개 미만입니다. */
if(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n You Must Have At least Two Hard Disks
Attached to your Computer To Run This");
printf("\n Program. Press any Key to Exit... ");
getch();
exit(1);
}
/// 첫 번째 하드 디스크(0x80)의 매개변수 가져오기 \\\
Sectors_in_HDD1 = getdrivegeometry (0x80);
printf(" Total Sectors in First Hard Disk = %lu\n\n",
Sectors_in_HDD1);
/// 두 번째 Hsrd 디스크의 매개변수 가져오기(0x81) \\\
Sectors_in_HDD2 = getdrivegeometry (0x81);
printf(" Total Sectors in Second Hard Disk = %lu\n\n",
Sectors_in_HDD2);
/// 먼저 확인 후 진행 \\\
printf("\n All The Data in Second Hard Disk will be
lost !!!");
printf("\n Press \'Y\' to Continue, Else any key to
Exit... ");
choice = getche();
switch(choice)
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
/* 대상은 소스보다 작아서는 안 됩니다 */
if(Sectors_in_HDD2<Sectors_in_HDD1)
{
printf("\n\n Destination Disk should not be Smaller
than Source Disk");
printf("\n Press any Key to Exit...");
getch();
exit(0);
}
/* 모든 것이 정상이면 원본 디스크의 모든 섹터를 대상 하드 디스크에 복사합니다 */
gotoxy(10,15);printf("Copying Absolute Sector: ");
for(loop=0;loop< =Sectors_in_HDD1;loop=loop+120)
{
readabsolutesectors ( 0x80, loop, 120, buffer );
writeabsolutesectors ( 0x81, loop, 120, buffer );
gotoxy(36,15); printf("%ld",loop);
if(kbhit())
{
exit(0);
}
}
//// 완료 메시지 표시 \\\
printf("\n\n Disk Imaging is Now Completed, Press any Key
To Exit...");
getch();
}
//// End of main
코딩에 대한 의견:
앞서 제공된 프로그램 코딩에서 디스크 이미징을 위해 다음 작업을 수행하여 진행합니다.
- 구조, 기하학은 INT 13H 확장, 기능 번호 0x48을 사용하는 getdrivegeometry 기능에서 사용됩니다. INT 13H 확장에 대한 자세한 설명은 이 책의 앞부분에서 논의한 "대용량 하드 디스크 처리" 장을 참조하십시오.
디스크의 여러 매개변수를 나타내는 데이터 유형은 다음과 같은 의미를 갖습니다.
Data Type |
Size in Bytes |
Description |
unsigned int size |
2 Bytes |
Size of Buffer |
unsigned int flags |
2 Bytes |
Information Flags |
unsigned long cyl |
4 Bytes |
Number of Physical Cylinders on Drive |
unsigned long heads |
4 Bytes |
Number of Physical Heads on Drive |
unsigned long spt |
4 Bytes |
Number of Physical Sectors Per Track |
unsigned long sectors[2] |
8 Bytes |
Total Number of Sectors on Drive |
unsigned int bps |
2 Bytes |
Bytes Per Sector |
- diskaddrpacket 구조는 readabsolutesectors 및 writeabsolutesectors 함수에서 사용됩니다. 디스크 주소 패킷의 형식은 다음 표에 나와 있습니다.
Data Type |
Size in Bytes |
Description |
char packetsize |
1 Byte |
Size of Packet, generally 10H |
char reserved |
1 Byte |
Reserved (0) |
int blockcount |
2 Bytes |
Number of Blocks to Transfer |
char far *bufferaddress |
4 Bytes |
address to Transfer Buffer |
unsigned long blocknumber[2] |
4 Bytes |
Starting Absolute Block Number |
- getdrivegeometry 함수는 지정된 드라이브의 매개변수를 가져오는 데 사용됩니다. 함수 getdrivegeometry는 INT 13H 확장의 함수 번호 0x48을 사용합니다.
매개변수의 의미는 다음 표에 설명되어 있습니다.
Parameter |
What it means |
i.h.ah = 0x48 |
Function Number 0x48 of INT 13H Extensions |
i.h.dl = drive |
Drive Number |
i.x.si = FP_OFF ( (void far*)&g ) |
ds:si address to buffer for drive parameters as discussed earlier |
s.ds = FP_SEG ( (void far*)&g ) |
ds:si address to buffer for drive parameters as discussed earlier |
int86x(0x13, &i, &o, &s) 함수는 세그먼트 레지스터 값으로 인터럽트 13H를 호출합니다. getdrivegeometry 함수는 드라이브의 총 수를 반환합니다.
- main() 함수에서 (char)peekb(0x0040, 0x0075); (pekb 함수는 DOS.H에 정의되어 있음) 시스템에 연결된 하드 디스크의 수를 반환합니다.
시스템에 연결된 하드 디스크의 수는 메모리 위치 0040H:0075H(세그먼트 0040H: 오프셋 0075H)에 저장된 바이트로 표시됩니다. 시스템에 연결된 하드 디스크의 수가 적으면 두 개의 프로그램이 오류 메시지를 표시하고 종료됩니다.
Sectors_in_HDD1 = getdrivegeometry(0x80); 첫 번째 하드 디스크(0x80)의 매개변수를 가져오고 첫 번째 하드 디스크의 총 섹터 수를 반환합니다.
Sectors_in_HDD2 = getdrivegeometry(0x81)와 유사합니다. 두 번째 하드 디스크(0x81)의 매개변수를 가져오고 두 번째 하드 디스크의 총 섹터 수를 반환합니다.
사용자가 이미징을 계속하도록 확인한 후 먼저 원본 하드 디스크의 크기가 대상 하드 디스크의 크기보다 크지 않아야 한다는 조건을 확인합니다. 목적지가 더 작으면 오류 메시지를 표시하고 종료합니다.
모든 것이 제대로 진행되고 있다면 원본 디스크의 섹터를 대상 디스크로 복사하십시오. 여기서 우리는 이미징 프로세스를 더 빠르게 만들기 위해 한 번에 61440바이트(각 512바이트의 120섹터)를 읽고 쓰고 있습니다.
64K 제한을 넘어서도 한 번에 더 많은 섹터를 사용하려면 “거대한 포인터” 대용량 메모리 모델에서 사양의 예는 다음과 같습니다.
char huge array[100000L];
- 함수, readabsolutesectors( 0x80, 루프, 120, 버퍼 ); unsigned long integer 루프로 지정된 섹터 번호부터 시작하여 첫 번째 하드 디스크(0x80)의 120개 섹터를 읽고 데이터 버퍼에 데이터를 저장합니다.
- 함수, writeabsolutesectors ( 0x81, 루프, 120, 버퍼 ); unsigned long integer 루프에 의해 지정된 섹터 번호부터 시작하여 두 번째 하드 디스크(0x81)의 120개 섹터에 데이터 버퍼의 데이터를 씁니다.
readabsolutesectors( ) 및 writeabsolutesectors( ) 함수의 코딩은 다음과 같습니다.
//// 절대 섹터를 읽는 기능 \\\\
int readabsolutesectors ( int drive,
unsigned long sectornumber,
int numofsectors,
void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* packet size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ; /* Number of sectors
to read */
/* 데이터 버퍼용 */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sector number
to read */
pp.blocknumber[1] = 0 ; /* Block number */
i.h.ah = 0x42 ; /* Function Number*/
i.h.dl = drive ; /* Physical Drive Number */
i.x.si = FP_OFF ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
/* 세그먼트 레지스터 값으로 INT 13H의 지정된 기능을 호출합니다. */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; /*failure */
else
return 1 ; /* success */
}
//// 절대 섹터 쓰기 기능 \\\\
int writeabsolutesectors ( int drive,
unsigned long sectornumber,
int numofsectors,
void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* Packet Size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ; /* Number of Sectors
to be written */
/* 데이터 버퍼용 */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ;/* Sector number
to be written */
pp.blocknumber[1] = 0 ; /* Block number = 0 */
i.h.ah = 0x43 ; /* Function Number */
i.h.al = 0x00 ; /* Write Flags, see
comments */
i.h.dl = drive ; /* Physical Drive number*/
/* ds:si for buffer Parameters */
i.x.si = FP_OFF ( (void far*)&pp ) ;
/* ds:si for buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* 세그먼트 레지스터 값으로 INT 13H의 지정된 기능을 호출합니다 */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; /* failure */
else
return 1 ; /* success */
}
코딩에 대한 의견:
두 함수에서 사용하는 매개변수는 다음과 같은 의미를 갖습니다.
Parameter |
Size in Bytes |
Description |
pp.packetsize = 16 ; |
1 Byte |
Size of packet = 10H |
pp.reserved = 0 ; |
1 Byte |
Reserved = 0 |
pp.blockcount = numofsectors ; |
2 Bytes |
Number of sectors to read |
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer)); |
----- |
for Data buffer or Transfer Buffer |
pp.blocknumber[0] = sectornumber ; |
4 Bytes |
Sector number to read/write (generally, we need only this). Only alone This can support up to 2.1 Terabytes. |
pp.blocknumber[1] = 0 ; |
4 Bytes |
Block number. Use this, If accessing the disk of greater then 2.1 Terabytes in size. |
i.h.ah = 0x42 ; or i.h.ah = 0x43 ; |
2 Bytes |
Function Number of INT 13H Extensions |
i.h.al = 0x00 ; |
1 Byte |
Write Flags used in write function only,00H, 01H are used for Write Without Verify and 02H is used for write with verify |
i.h.dl = drive ; |
2 Bytes |
Physical Drive Number |
i.x.si = FP_OFF ( (void far*)&pp ) ; |
------ |
ds:si for buffer Parameters |
s.ds = FP_SEG ( (void far*)&pp ) ; |
------ |
ds:si for buffer Parameters |
int86x ( 0x13, &i, &o, &s ) ; |
------ |
Invoke the specified Function of INT 13H with segment register values |