부트로더와 커널 프로그램을 각각 만든 후 합쳐서 디스크에 넣는 프로그램인데요..
먼저 부트로더는 다음과 같이 작성하고,
;boot1.asm
[org 0]
[bits 16]
jmp 0x07C0:start
start:
mov ax, cs
mov ds, ax
mov ax, 0xB800
mov es, ax
mov di, 0
mov ax, word [msgBack]
mov cx, 0x7D0 ; 글자의 갯수인 0x7D0을 cx에 지정해 카운터로 사용한다.
draw:
mov word [es:di], ax ; ax에 있는 배경색을 비디오 램 영역인 0xB8000에 복사
add di, 2 ; di를 2씩 증가 (글자 하나당 2byte이기 때문)
dec cx ; 한 번 쓸때마다 cx를 dec, 즉 1씩 감소시킨다.
jnz draw ; Zero Flag가 0인동안 루프를 반복한다(jnz는 Jmp Not Zero의 약자)
read:
mov ax, 0x500
mov es, ax
mov bx, 0 ; Road Kernel ES:BX, 0x500:0000
mov ah, 2 ; Read
mov al, 1 ; Serctors to read count
mov ch, 0 ; Cyilnder : 0-79
mov cl, 2 ; Sectory : 1-18
mov dh, 0 ; Head : 0-1
mov dl, 0 ; Drive : Floppy A
int 0x13 ; interrupt 13h
jc read ; Error가 발생하면 다시 읽기
jmp 0x500:0000 ; kernel.bin이 위치한 곳으로 점프한다.
end:
msgBack db ' ', 0x7F
times 510-($-$$) db 0
dw 0xAA55
-------------------------------------------------------------------------
그 다음 커널 프로그램을 아래와 같이 작성했는데요.
; kernel1.asm
[org 0]
[bits 16]
kernel_start:
mov ax, cx
mov ds, ax
xor ax, ax ; ax를 0으로 초기화하기 위해 xor를 사용
mov ss, ax ; 스택세그먼트를 0으로 초기화
lea si, [msgKernel] ; lea라는 명령어를 통해서 문자열이 저장되어있는 곳의 주소를 구한다
mov ax, 0xB800
mov es, ax ; es에 0xB800을 넣는다.
mov di, 0 ; 화면에 제일 처음 부분부터 시작할 것이다.
call printf
jmp $
printf:
push eax
printf_loop:
mov al, byte [si] ; si가 가리키는 주소에서 문자를 하나 꺼내온다
mov byte [es:di], al ; 문자를 화면에 나타낸다
or al, al ; al이 0인지를 알아본다.
jz printf_end ; 0이라면 printf_ed로 점프한다.
inc di
mov byte [es:di], 0x0F
inc si ; 다음 문자를 꺼내기 위해서 si를 하나 증가
inc di ; 화면에 다음 문자를 나타내기 위해 di를 증가
jmp printf_loop ; 루프를 돈다
printf_end:
pop eax
ret
msgKernel db "We are in kernel program", 0
TIMES 1474048-($-$$) db 0 ; 플로피 디스크 사이즈를 1.44M로 만든다.
--------------------------------------------------------------------------------------
위의 두 코드를 작성하고, 컴파일 한 후에 COPY명령어를 통해서 합쳐서 .img파일을 만든 후 QEMU 프로그램을 사용해서
qemu-system-x86_64.exe -L . -m 64 -fda E:/OS/Source/chap02/os.bin -localtime -M pc 다음과 같이 편집한 후 실행해서
확인해봤더니 We are in Kernel program이라는 메시지가 떠야하는데, 그냥 검은화면만 뜨고 아무메시지도 안나오네요..
이거 정확히 머가 문제인지 모르겠습니다 ㅠㅠ 도와주세요
제가 알기로는 INT 0x13 BIOS 명령어를 사용하기 위해서는 fdd size가 1.44M가 되지 않으면 INT 0x13이 적용되지 않는다고 해서
TIMES 1474048-($-$$) db 0를 추가했는데도 똑같네요.. 머가 문제죠??
댓글 달기