x86-64 운영체제를 만들자 [II] 시작이 반이다, 부트로더
기존 강좌 보기: http://kldp.org/taxonomy/term/3663
되돌아보기
1부에서는 레거시 모드와 롱 모드의 차이, 그리고 두 모드 사이를 전환하는 방법에 대하여 알아보았습니다.
2부에서는 레거시 모드와 롱 모드에 대한 생각에서 벗어나서, 일단 부트로더를 만들어 보겠습니다.
부트로더의 동작부트로더는 동작합니다. 고로 존재...(*shot*)
어쨌든 부트로더는 BIOS로부터 제어권을 받습니다.
BIOS는 POST(Power On Self Test)를 마치고 부트로더를 읽어들여서 0x07c0:0000에 저장해 줍니다.
그리고 제어권을 넘겨주죠.
운영체제 이름짓기
뭐 강좌 예제이니만큼 ABC64라고 하죠.
부연 설명을 드리자면 A Bery Cimple 64-bit OS입니다. (농담인 거 아시죠?)
자 실제로 만들어볼까요?
이런 코드입니다.
[org 0] [bits 16] jmp 0x07c0:start start: mov ax, 0x0f00 mov es, ax mov bx, 0x0000 mov ah, 2 mov al, 2 mov ch, 0 mov cl, 2 mov dh, 0 mov dl, 0 int0x13: int 0x13 jc int0x13 off_floppy_motor: xor dx, 0x3f2 xor al, al out dx, al cli jmp 0x0f00:0000 times 510-($-$$) db 0 db 0x55 db 0xaa
[org 0]문의 역할
원점을 0으로 잡아줍니다. 즉, 이 코드가 실행되는 위치를 잡아주는 것이죠.
start가 offset 5에 있는데, jmp 0x07c0:start 문이 있습니다.
그러면 [org 0]일 때는 jmp 0x07c0:start = jmp 0x07c0:0x0005이지만,
[org 0x10]일 때는 jmp 0x07c0:start = jmp 0x07c0:0x0015가 되는 것이죠.
하지만 BIOS는 0x07c0:0000부터 로드해 주기 때문에 [org 0]을 사용해야겠죠?
[bits 16]문: 이 프로그램은 리얼 모드에서 돌아갑니다.
NASM 어셈블러에게 지시해 주는 문장이죠.
jmp 0x07c0:start
코드 세그먼트 레지스터에 0x07c0을 넣어주기 위한 편법입니다.
far jump를 빙자한 대입문 -_-&
그 다음 문장들
* AX를 통하여 ES에 0x0f00을 대입합니다.
* BX에는 0x0000을 대입합니다. 커널로더가 로드되는 위치는 ES:BX이니까 0x0f00:0000
* 각종 숫자들을 설정하고 int 0x13으로 읽어들입니다.
* 실패하면 캐리 플래그가 set되는데, 실패할 경우 int 0x13을 다시 실행하도록 jc문을 사용했습니다.
* 자 이제 커널로더로 점프. 이제 커널로더가 64비트 모드로 전환한 뒤 간이 플로피 드라이버를 통해 커널을 읽어들입니다.
* 부트로더의 소임은 이제 끝났습니다.
이상입니다.
허접한 강좌 읽어주셔서 감사합니다.
32bit와 거의
32bit와 거의 흡사하군요.
근데,
위 문장처럼 64비트 모드로 전환하는 곳이 어디있는지 안보이네요. 제가 보기엔 16bit Realmode 거든요.
아닌가요? ^-^
----
MyWiki http://linu.sarang.net
----
;p $ rm -rf ~ && mkdir ~ && wget $열정 and $연애
----
http://linu.sarang.net, http://wbhacker.tistory.com
소스상에는 커널로더로 점프하는 부분만 있습니다.
위에 나온 소스에는 점프 부분 밖에 없으니 이후에 나올 내용이 될 겁니다.
jmp 0f00:0000이 읽은 Sector의 시작점이므로 여기에 커널 로더가 있겠죠?
댓글 달기