OS(5) プロテクトモードへ移行
次の内容で作成してみる。
- フラットモデルとする
- IPLの動作は呼び出すプログラムを2セクタ分とする以外同じ
- 最初のセクタは(setup)、IPLから直接呼ばれ、GDTの設定とプロテクトモードへの移行を行うプログラムを入れる
- 次のセクタ(kernel)はプロテクトモードで動作し、VRAMにメッセージを書き込む。
無事動作完了。
次は割り込みだ。
Makefile(GNU make用)
os.img: os.bin ruby makeFDimage.rb $< $@ os.bin: ipl.bin setup.bin kernel.bin copy /b ipl.bin+setup.bin+kernel.bin $@ ipl.bin: ipl.asm nasm -o $@ $< setup.bin: setup.asm defs.inc nasm -o $@ $< kernel.bin: kernel.asm defs.inc nasm -o $@ $<
defs.inc
CSEG equ 0x10 DSEG equ 0x18 VRAMOFS equ 0xb8000
setup.asm
IDTの初期化とかも入れていく予定
; ; setup.asm プロテクトモードカーネルの起動準備 ; %include "defs.inc" ; まずは 1000:0 で開始 ss:sp はIPL設定のまま start: mov ax, cs mov ds, ax cli ; 割り込み禁止 lgdt [GDTR] ; GDTの設定 mov eax, cr0 ; プロテクモードへ移行 or eax, 1 mov cr0, eax jmp .@flush ; パイプラインをフラッシュしてjump .@flush: jmp dword CSEG:PROTECT_start + 0x10000 ;; db 0x66, 0xea ;; dd PROTECT_start + 0x10000 ; アドレス補正 ;; dw CSEG GDTR: dw initial_GDT_end - initial_GDT - 1 dd initial_GDT + 0x10000 ; アドレス補正 initial_GDT: dw 0, 0, 0, 0 ; NULLセグメント dw 0, 0, 0, 0 ; ダミー dw 0xffff ; limit(0-15) dw 0 ; base(0-15) db 0, 0x9a ; base(16-23), code db 0xcf, 0 ; G,32bit,limit(16-19) dw 0xffff dw 0 db 0, 0x92 ; data db 0xcf, 0 initial_GDT_end: times 512 -( $ - $$) db 0 PROTECT_start:
kernel.asm
; ; kernel.asm ; [bits 32] [org 0x10200] %include "defs.inc" PROETCT_start: mov ax, DSEG mov ds, ax mov es, ax mov ss, ax mov esp, 0xa0000 ; メモリホール直前からスタック xor ax, ax mov fs, ax mov gs, ax mov esi, msg mov edi, VRAMOFS mov ah, 0x4f cld .@loop: lodsb stosw or al, al jnz .@loop jmp $ msg: db 'This is PROTECTED mode kernel', 0