이번에 운영체제를 공부하면서 만들어 본 부트로더 소스입니다.
그렇게 복잡하지는 않을 줄 알았는데 2주동안이나 걸려서 만든게
아직도 요모양입니다.
일단 활성 파티션은 찾아서 메세지를 출력하는 것 까지는
돌아가는데 윈도우를 실행시키는게 안됩니다.
KernelLoad 프로시저에 FAT를 읽어서 처음 섹터를 메모리로
읽어들여서 그쪽으로 ret하게 만들었습니다.
계속 생각해보고 있지만 뭐가 잘못된 건지를 모르겠습니다.
win95의 부트로더를 분석한 걸 읽어봤는데 저와 거의 흡사하게
한 섹터만 읽어서 그쪽으로 점프하던데요 저는 xp를 쓰고 있습니다.
제가 뭘 몰라서 못하고 있는건지 말씀해주시면 감사하겠습니다.
masm으로 만들었고여
partcopy test3.com 0 200 -f0
이렇게 디스크에 써서 디스크로 부팅했습니다.
<pre>
CodeSeg segment
assume cs:CodeSeg, ds:CodeSeg, ss:CodeSeg
Main proc
;실행을 시작할
mov ax, 7c0h
push ax
mov ax, offset start
push ax
retf
start:
cli
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax ; 모든 세그먼트 재설정
mov sp, offset main ; 스텍 포인터 변경
sti
;하드 디스크의 부트 섹터를 읽어서 메모리 0:1000h에 올립니다.
xor ax, ax
mov es, ax
mov dx, 0080h
mov cx, 0001h
mov ax, 0201h
mov bx, 1000h
int 13h
;si에 부트 섹터의 시작지점이 들어갑니다.
mov si, bx
push si
call FoundActive ;활성 드라이브를 찾습니다.
cmp ax, 0 ;활성 드라이브를 못 찾았을때
jz L_Error
mov si, offset HDDmsg ;활성 드라이브를 찾았을때
call PrintMsg ;메세지를 출력하는 프로시저
;다시 부트 섹터의 시작 지점을 로드합니다.
pop si
call LoadKernel ;커널을 로드합니다.
;활성 가능한 파티션이 없으면 에러메세지를 출력하고 멈춥니다.
L_Error:
mov si, offset PartError
call PrintMsg
L_Hang:
jmp L_Hang
Main endp
FoundActive proc
mov cx, 4 ;4개의 테이블이 있다.
add si, 1beh
L_ReadTable:
cmp cx, 0
jz L_NotFound
mov al, byte ptr es:[si] ;테이블을 읽는다.
cmp al, 80h ;활성인지를 검사한다.
jz L_Found ;활성을 찾았다.
;활성이 아니라면
add si, 10h ;다음 테이블을 읽기위해 10h를 더한다.
dec cx
cmp al, 00 ;비활성이라면
jz L_ReadTable ;다음 테이블을 읽는다.
;80h, 00h도 아니면 파티션 에러다.
L_NotFound:
mov ax, 0
ret
L_Found:
dec cx
add si, 10h
mov al, byte ptr es:[si] ;테이블을 읽는다.
cmp al, 80h ;활성인지를 검사한다.
jz L_NotFound ;또 활성이면 에러
cmp al, 00
jnz L_NotFound ;80h, 00h도 아니면 에러다.
cmp cx, 1 ;마지막 테이블까지 읽었으면 끝낸다.
jnz L_Found
;활성 파티션이 하나이고 에러가 없을때
mov ax, 0ffh
ret
FoundActive endp
;si에 들어있는 ascz 메세지를 읽어서 출력합니다.
;인자 : si
PrintMsg proc
L_PrintChar:
mov al, byte ptr cs:[si]
cmp al, 0
jz L_PM
mov bx, 0007h
mov ah, 0eh
int 10h
inc si
jmp L_PrintChar
L_PM:
ret
PrintMsg endp
;부트 섹터에서 FAT를 읽어서 데이타 영역의 첫 섹터를 찾아
;0:0600h에 로드해서 점프합니다.
LoadKernel proc
xor ax, ax
mov es, ax
mov ax, 0201h
add si, 1beh
mov dx, word ptr es:[si] ;FAT의 1,2 바이트를 읽습니다.
add si, 2
mov cx, word ptr es:[si] ;FAT의 다음 두 바이트를 읽습니다.
mov bx, 0600h
int 13h
;커널을 로드한 지점으로 점프합니다.
xor ax, ax ;세그먼트 푸쉬
push ax
mov ax, 0600h ;오프셋 푸쉬
push ax
ret ;점프?
LoadKernel endp
HDDmsg db "Founded active HDD drive", 0
PartError db "Can't find active partition", 0
db 11ah dup (?)
db 55H, 0AAH
CodeSeg ends
end Main
</pre>
--