gdt_desc: ; The GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt+0x10000 ; Address of the GDT
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0
dd 0
gdt_code: ; Code segment, read/execute, nonconforming
dw 0FFFFh
dw 0x0000
db 0x01
db 10011010b
db 11001111b
db 0
gdt_data: ; Data segment, read/write, expand down
dw 0FFFFh
dw 0x0000
db 0x01
db 10010010b
db 11001111b
db 0
gdt_video:
dd 0x8000FFFF, 0x0040920B
gdt_end: ; Used to calculate the size of the GDT
linef :
mov ax, di
add di, 160
inc si
jmp print_loop
carr :
xor dx, dx
mov ax, di
mov bx, 160
div bx
mul bx
mov di, ax
inc si
jmp print_loop
puts :
xor edi, edi
print_loop :
mov dl, [si]
cmp dl, 10 ;linefeed
je linef
cmp dl, 13 ;carriage return
je carr
cmp dl, 0
je endputs
mov byte[es:di], dl
inc di
mov byte[es:di], 0x06
inc di
inc si
jmp print_loop
endputs :
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;end kernel;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32bit Protected Mode로 진입하여, 문자열 찍기.
32비트 키는 순간 재부팅이 되어서 무엇이 문제인지 모르고 있다가 32비트에선 바이오스 인터럽트가 먹히지 않는 다는 것에 코드를 다시 수정하고 어셈 파일을 두개로 나눠서 작성하였다.
0x1000:0000으로 Far 점프를 하기 위해 gdt 코드 세그먼트, 데이타 세그먼트의 베이스 어드레스를 dw 0x0000 db 0x01로 하여 베이스를 0x00010000로 맞춰주었다.
;;;;;;;;;;;;;;;;;;;;;;;;;build.sh;;;;;;;;;;;;;;;;;;;;;;;;;;
rm -f boot kernel image.img
nasm boot.asm -o boot
nasm kernel.asm -o kernel
dd if=boot of=image.img seek=0
dd if=kernel of=image.img seek=1
dd if=boot of=image.img seek=2880
;;;;;;;;;;;;;;;;;;;;;;;end build;;;;;;;;;;;;;;;;;;;;;;;;;;;
build.sh를 사용하여 boot.asm과 kernel.asm의 바이너리 파일을 만들고 그파일을 image.img파일로 맞춰주었다. if=FILE (read from FILE instead of stdin)
of=FILE (write to FILE instead of stdout)
seek=BLOCKS (skip BLOCKS obs-sized blocks at start of output)
저번에 다른 블로그에서 본 disk 섹터를 메모리에 읽는 인터럽트 마지막에 jmp 0x1000:0000이 왜 써져있나 싶어서 이것을 지우고 사용하였는데 파일을 두개로 하기때문에 far jump를 하여 세그먼트가 조정되어서 사용한다는 것을 알게 되었다.