R&D/OS

부트로드 만들기 예제

sunshout 2013. 5. 6. 16:22


[정리] Linux Kernel_bootloader.pdf

부트로드 예제 만들기

가상화가 보편화 되면서 부트로더, 커널 등을 개발하고 테스트하는 것이 쉬워 졌다.

부트로더는 16bit 로 동작하며, 0x7c00 주소의 instruction을 실행한다.

 

왜 0x7c00 일까요?

컴퓨터가 켜지고 BIOS가 실행되면, BIOS는 디스크가 "bootable" 한지를 체크하게 된다.

이 때 boot sector(디스크의 첫번째 sector?)의 511 bytes, 512 bytes를 읽게 된다

해당 위치에 0x55, 0xAA (Magic code)가 있으면 부트로드로 간주하고, 해당 sector를 메모리 공간 0x0000:0x7c00(segment 0, address 0x7c00)로 로드한다.

 

다음 코드는 아무런 동작도 하지 않은 부트로드이다.

예제코드(bootloader.asm)

bits 16 ; tell the assembler that it's a 16 bit code

org 0x7c00

 

jmp $ ; infinite loop

 

times 510 - ($ - $$) db 0 ; fill the rest of sector with 0

dw 0xAA55 ; add boot signature at the end of bootloader

 

. org 0x7c00 : assembly code가 0x7c00 주소부터 시작함을 의미한다.

. jmp $ : $는 현재 위치를 의미하는 것으로 현재 위치로 계속 점프(무한루프)

. $ - $$ : $는 현재 위치, $$는 프로그램의 시작위치

따라서 times 510-($-$$) 는 510에서 프로그램의 크기만큼을 땐 것이고, 이를 0(zero)로 패딩한다.

부트로드는 512bytes 크기이며, 부트로드의 마직막에는 매직코드인 0XAA55를 넣어야 하기 때문에 510-(프로그램 크기)로 패딩을 해야 한다.

 

nasm syntax

DB : write bytes(8 bits)
DW : write words (16 bits)
DD : Write double words (32 bits) 

컴파일하기

이제 부트로드가 포함된 디스크 이미지를 만들면 된다. nasm을 이용해서 -f bin 옵션을 주고 컴파일을 수행하면 된다.

nasm bootloader.asm -f bin -o os.img

 

Xen에서 HVM으로 부팅하기 (vm.cfg)

이제 부트로드가 포함된 디스크 이미지를 가지고 VM을 부팅해 보자. HVM으로 부팅하기 때문에 에뮬레이터된 BIOS는 우리가 만든 디스크 이미지의 첫번째 섹터를 읽어서 0x7c00 주소에 로드를 할 것이다. 0x7c00 주소에는 jmp $ 명령어가 있을 것이고, 아무런 동작도 하지 않을 것이다.

 

VM을 xl 또는 xe를 통해서 부팅하기 위한 설정정보는 아래와 같다. Builder를 hvm으로 설정만 하면 된다.

name = 'tiny'

builder='hvm'

memory=2048

disk = ['file:/home/SR/tiny/os.img,hda,w']

#boot = 'dc'

on_poweroff = 'destroy'

on_reboot = 'restart'

on_crash = 'restart'

vnclisten = '0.0.0.0'

vncpasswd = ''

vncconsole = 1

 

xl 명령어를 통해서 vm을 시작하면,

[root@openxen tiny]# xl create vm.cfg

Parsing config from vm.cfg

xc: info: VIRTUAL MEMORY ARRANGEMENT:

Loader: 0000000000100000->000000000019c824

Modules: 0000000000000000->0000000000000000

TOTAL: 0000000000000000->000000007f800000

ENTRY ADDRESS: 0000000000100000

xc: info: PHYSICAL MEMORY ALLOCATION:

4KB PAGES: 0x0000000000000200

2MB PAGES: 0x00000000000003fb

1GB PAGES: 0x0000000000000000

Daemon running with PID 29089

[root@openxen tiny]# xl list

Name ID Mem VCPUs State Time(s)

Domain-0 0 2048 8 r----- 22790.6

centos2 93 2048 1 -b---- 4831.7

centos63 110 2048 1 -b---- 483.0

tiny 121 2048 1 r----- 1.9

[root@openxen tiny]#

 

아래와 같이 VNC를 통해서 접속을 확인해 보면, hard disk로 부팅을 한다는 메시지만 나오고 아무런 동작을 하고 있지 않음을 알 수 있다.

 

bits 16

org 0x7c00


mov si, welcome

call print_string


print_string:

    lodsb

    or al, al

    jz .done

    mov ah, 0x0E

    int 0x10

    jmp print_string


.done:

    ret


welcome db 'Welcome Son', 0x0D, 0x0A, 0


times 510 - ($ - $$) db 0

dw 0xAA55



참조: 

http://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part