Search

플로피 디스크 OS 이미지 로딩

대분류
CS
소분류
OS
유형
C
시스템 프로그래밍
최종 편집 일시
2024/10/27 16:05
생성 일시
2022/04/04 07:18
15 more properties

섹터 읽기

include <stdio.h> int main(int argc, char* argv[]) { int iTotalSectorCount = 1024; int iSectorNumber = 2; int iHeadNumber = 0; int iTrackNumber = 0; //실제 이미지를 복사할 어드레스(물리주소) char* pcTargetAddress = (char*)0x10000; while(1) { //전체 섹터 수를 하나씩 감소시키면서 0이 될때까지 섹터를 복사 if(iTotalSectorCount == 0) { break; } iTotalSectorCount = iTotalSectorCount - 1; //1섹터를 읽어들여서 메모리 어드레스에 복사 //BIOSReadOneSector: BIOS 섹터읽기 기능을 호출하는 임의의 함수 if(BIOSReadOneSector(iSectorNumber, iHeadNumber, iTrackNumber, pcTargetAddress) == ERROR) { HandleDiskError(); } //1섹터는 512(0x200) 바이트이므로, 복사한 섹터 수만큼 어드레스 증가 pcTargetAddress = pcTargetAddress + 0x200; //섹터->헤드->트랙 순으로 번호 증가 iSectorNumber = iSectorNumber + 1; if(iSectorNumber < 19) { continue; } iHeadNumber = iHeadNumber ^ 0x01; //헤드의 번호는 0과 1이 반복되므로 XOR 연산을 이용 iSectorNumber = 1; if (iHeadNumber != 0) { continue; } iTrackNumber = iTrackNumber + 1; } return 0; } void HandleDiskError() { printf("DISK Error!"); while(1); }
C++
복사

어셈블리어 섹션 코딩

TOTALSECTORCOUNT: dw 1024 ; 부트로더를 제외한 os이미지의 크기 ; 최대 1151섹터(0x90000byte)까지 가능 SECTORNUMBER: db 0x02 ; os이미지가 시작하는 섹터번호를 저장하는 영역 HEADNUMBER: db 0x00 ; os이미지가 시작하는 헤드번호를 저장하는 영역 TRACKNUMBER: db 0x00 ; os이미지가 시작하는 트랙번호를 저장하는 영역 ; 디스크의 내용을 메모리로 복사할 어드레스(ES:BX)0x10000으로 설정 mov si, 0x1000 ; os이미지를 복사할 어드레스(0x10000); 세그먼트 레지스터 값으로 변환 mov es, si ; ES세그먼트 레지스터에 값 설정 mov bx, 0x0000 ; BX레지스터에 0x0000을 설정하여 복사할 ; 어드레스를 0x1000:0000(0x10000)으로 최종 설정 mov di, word [ TOTALSECTORCOUNT ] ; 복사할 os이미지의 섹터 수를 DI레지스터에 설정 READATA: ; 디스크를 읽는 코드의 시작 ; 모든 섹터를 다 읽었는지 확인 cmp di, 0 ; 복사할 os 이미지의 섹터 수를 0과 비교 je READEND ; 복사할 섹터 수가 0이라면 다 복사 했으므로 READEND로 이동 sub di, 0x1 ; 복사할 섹터 수를 1감소 ;;;;;;;;;;;;;;;;;;;;;;;;; ; BIOS Read Function 호출 ;;;;;;;;;;;;;;;;;;;;;;;;; mov ah, 0x02 ; BIOS 서비스 번호 2(Read Sector) mov al, 0x01 ; 읽을 섹터 수는 1 mov ch, byte [ TRACKNUMBER ] ; 읽을 트랙 번호 설정 mov cl, byte [ SECTORNUMBER ] ; 읽을 섹터 번호 설정 mov dh, byte [ HEADNUMBER ] ; 읽을 헤드 번호 설정 mov dl, 0x00 ; 읽을 드라이브 번호(0=Floppy)설정 int 0x13 ; 인터럽트 서비스 수행 jc HANDLEDISKERROR ; 에러가 발생했다면 HANDLEDISKERROR로 이동 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 복사할 어드레스와 트랙, 헤드, 섹터 어드레스 계산 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; add si, 0x0020 ; 512(0x200)바이트만큼 읽었으므로, 이를 세그먼트 레지스터 값으로 변환 mov es, si ; ES 세그먼트 레지스터에 더해서 어드레스를 한 섹터만큼 증가 ; 한 섹터를 읽었으므로 섹터 번호를 증가시키고 마지막 섹터(18)까지 읽었는지 판단 ; 마지막 섹터가 아니면 섹터 읽기로 이동해서 다시 섹터 읽기 수행 mov al, byte [ SECTORNUMBER ] ; 섹터번호를 AL 레지스터에 설정 add al, 0x01 ; 섹터번호를 1 증가 mov byte [ SECTORNUMBER ], al ; 증가시킨 섹터번호를 SECTORNUMBER에 다시 설정 cmp al, 19 ; 증가시킨 섹터번호를 19와 비교 jl READDATA ; 섹터번호가 19미만이라면 READDATA로 이동 ; 마지막 섹터까지 읽었으면(섹터번호가 19이면) 헤드를 토글(0->1, 1->0)하고, ; 섹터번호를 1로 설정 xor byte [ HEADNUMBER ], 0x01 ; 헤드번호를 0x01과 XOR하여 토글(0->1, 1->0) mov byte [ SECTORNUMBER ], 0x01 ; 섹터 번호를 다시 1로 설정 ; 만약 헤드가 1->0으로 바뀌었으면 양쪽 헤드를 모두 읽은 것이므로 아래로 이동하여 ; 트랙 번호를 1증가 cmp byte [ HEADNUMBER ], 0x00 ; 헤드번호를 0x00과 비교 jne READDATA ; 헤드번호가 0이 아니면 READDATA로 이동 ; 트랙을 1증가시킨 후, 다시 섹터 읽기로 이동 add byte [ TRACTNUMBER ], 0x01 ; 트랙번호를 1증가 jmp READDATA ; READDATA로 이동 READEND: HANDLEDISKERROR: ; 에러를 처리하는 코드 ;;;생략;;; jmp $
C
복사