OS(4) リアルモードのカーネルを呼び出してみる
Chapter 02に倣ってIPLの次のセクタに配置されているプログラムをカーネルと見立ててロードしてみる。
ipl.asm
- スタックをIPLの直前へ明示的に設定
- 画面を青色で埋める
- プログラムを 1000:0000 へロードする
- FDが読めなかったときは int 0x18 を呼び出し、後はBIOSへ任せる
- 正しく読めたときは 1000:0000 へジャンプ
青色で埋めるのはVRAM直書きのほか、VIDEO BIOS(int 10)を試してみた。
; ; IPL.asm ; [org 0x7c00] jmp 0:start ; 一応 0:7c00 へ正規化 ; (のつもり) start: mov ax, cs mov ds, ax cli ; 念のためスタックを設定 mov ss, ax mov sp, 0x7c00 sti %if 0 ; VRAM直書き mov ax, 0xb800 ; 画面を青色 mov es, ax xor di, di mov cx, 80 * 25 ; 80 * 25 = 2000文字分 mov ax, 0x1720 ; 背景青でで空白(' ')を埋める cld rep stosw %else ; VIDEO BIOSを使用 mov ah, 0x02 ; カーソルを左上へ xor bh, bh xor dx, dx int 0x10 mov ax, 0x0920 ; 2000文字属性指定して書き込み mov bx, 0x0017 mov cx, 80 * 26 int 0x10 %endif ; カーネルをロード(IPLの次の2セクタ) load: mov ax, 0x1000 ; ロードアドレス es:bx mov es, ax ; es = 1000 xor bx, bx ; bx = 0000 mov cx, 0x0002 ; シリンダ 0, セクタ 2 mov dx, 0x0000 ; ヘッド 0, ドライブ 0 mov ax, 0x0201 ; 1セクタ読み出し int 0x13 jnc jmp_kernel ; 成功ならカーネルへ int 0x18 ; 'Reboot and ..' と表示される jmp_kernel: jmp 0x1000:0 ; カーネルへ far jump times 510 - ($ - $$) db 0 dw 0xaa55
カーネル(と見立てたプログラム)
単にメッセージを表示して終わり。表示には VIDEO BIOSを使用。
; ; rkernel.asm リアルモードカーネル @ 1000:0 ; start: mov ax, cs mov ds, ax mov es, ax ; cli ; IPLの設定を引き継ぐ ; mov ss, ax ; xor ax, ax ; mov sp, ax ; sti mov si, msg call puts jmp $ puts: mov ah, 0x0e .@loop: lodsb or al, al jz .@ret int 0x10 jmp short .@loop .@ret: ret msg: db 'This is REAL mode kernel', 0