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