MINT64 OS

64bit 멀티코어 OS 제작하기 [4] - 3 : 부트 로더 테스트용 가상 이미지 제작

Sqix_ow 2018. 5. 28. 17:07

부트 로더를 만들었으니 테스트를 해야 합니다. OS 이미지가 전부 로드가 되는지 알아야 하기에, 충분한 크기의 테스트 이미지가 필요합니다. 부트로더에서 로드할 OS 이미지가 1024 섹터 (512b * 1024 == 512KB)를 가지기 때문에 해당 크기를 갖는 가상 OS 이미지를 제작하여 테스트할 것입니다.


이미지가 너무 커서, 직접 손으로 전부 작성하는 것은 사실상 불가능한 일이고, 코드를 생성하고 이를 반복하여 삽입하는 것으로 섹터를 만들어 보도록 합시다. 레지스터를 초기화한 뒤 0을 출력하도록 하고, 정상적으로 해당 섹터가 수행되면 SECTORCOUNT에 기록합니다. 이렇게 한 번의 동작 코드를 만든 후, 전처리기를 이용하여 1024번 반복하도록 하면, 1024의 섹터를 가지는 OS 가상 이미지가 생성됩니다.


[ORG 0x00]

[BITS 16]


SECTION .text


jmp 0x1000:START ; copy 0x1000 to CS, and goto START label


SECTORCOUNT: dw 0x0000

TOTALSECTORCOUNT: equ 1024


START:

; Register initialize

mov ax, cs

mov ds, ax

mov ax, 0xB800


mov es, ax


; Code generate on each sector

%assign i 0

%rep TOTALSECTORCOUNT

%assign i i+1

; convert sector's location to coordinates

mov ax, 2

mul word [ SECTORCOUNT ]

mov si, ax

; set result to video memory's offset and print 0 on 3rd line

mov byte [ es: si + (160 * 2) ], '0' + (i % 10)

add word [ SECTORCOUNT ], 1

; if (last sector) -> jmp $ || else go to next sector

%if i == TOTALSECTORCOUNT

jmp $

%else

jmp (0x1000 + i * 0x20): 0x0000

%endif


times ( 512 - ($ - $$) % 512 ) db 0x00

%endrep

여기서 전처리문이란, % 문자로 시작되는 것입니다. 전처리기 지시문은 여러 실행 환경에서 소스 프로그램을 변경하기 쉽고 컴파일하기 용이하게 만들기 위해 일반적으로 사용됩니다. 소스 파일의 지시문은 특정 작업을 수행하도록 전처리기에 지시합니다. 예를 들어 전처리기는 텍스트에서 토큰을 바꾸거나, 다른 파일의 내용을 소스 파일에 삽입하거나, 텍스트 섹션을 제거하여 파일 일부의 컴파일을 억제할 수 있습니다. 전처리기 코드 줄은 매크로 확장 전에 인식되고 수행됩니다. 따라서 매크로가 전처리기 명령처럼 보이는 항목으로 확장되는 경우 해당 명령은 전처리기에서 인식되지 않습니다.


위에서 사용된 전처리기는 다음과 같은 역할을 합니다.

%assign i 0 : i라는 변수를 생성하고 0으로 초기화

%rep TOTALSECTORCOUNT : %endrep까지 TOTALSECTORCOUNT 번 반복

%if i == TOTALSECTORCOUNT : i가 TOTALSECTORCOUNT와 같으면 아래 조건문 실행

%else : %if에서 거짓 조건인 경우 실행

%endif : if / else 블록 종료

%endrep : rep 블록 종료


이제 OS 이미지 소스코드가 생성되었습니다. 이를 빌드하기 위해 makefile을 kernel32에 생성하고, mint64 디렉토리의 makefile을 수정할 것입니다.


01.Kernel32/makefile


all: VirtualOS.bin


VirtualOS.bin: VirtualOS.asm

nasm -o VirtualOS.bin VirtualOS.asm


clean:

rm -f VirtualOS.bin


MINT64/makefile


all: BootLoader Kernel32 Disk.img


BootLoader:

@echo

@echo ============== Build Boot Loader ==============

@echo


make -C 00.BootLoader

@echo

@echo ============== Build Complete ==============

@echo


Kernel32:

@echo

@echo ============== Build 32bit Kernel =============

@echo

make -C 01.Kernel32

@echo

@echo ============== Build Complete ==============

@echo


Disk.img: BootLoader Kernel32

@echo

@echo ============== Disk Image Build Start ==============

@echo


cat 00.BootLoader/BootLoader.bin 01.Kernel32/VirtualOS.bin > Disk.img

@echo

@echo ============== All Build Complete ==============

@echo


clean:

make -C 00.BootLoader clean

make -C 01.Kernel32 clean

rm -f Disk.img


이제 make를 실행하여 빌드하고, qemu를 실행하여 봅시다. MINT64 디렉토리에서 다음 명령어를 실행합니다.


#make

#qemu-system-x86_64 -m 64 -fda ./Disk.img -localtime -M pc




이렇게 숫자가 1024개 생성이 됩니다. 섹터가 생성이 되면 0부터 9까지 숫자가 하나씩 생성되고, 다시 0의 숫자가 생성됩니다. 즉, 1024개의 섹터가 정상적으로 생성되었다는 것입니다. 만약, 1152개의 풀 섹터로 테스트해보고 싶다면 (0x10000 ~ 0xA0000까지만 사용할 수 있고, 그 이후는 비디오 메모리이기 때문에 1152개입니다.) TOTALSECTORCOUNT를 1152로 맞추어 보고 하면 됩니다. 그 이후에는 비디오 메모리를 침범하기 때문에 에러가 날 것입니다.(아마 QEMU가 에러 메시지를 뿜뿜하고 꺼질 겁니다)


이제 32비트 커널을 본격적으로 만들어 보면서, OS에 대한 심화된 공부를 시작해 봅시다!


감사합니다.