2014年9月16日火曜日

[OS作成]30日でできる!OS自作入門 3日目 (1)

次の課題は、ブートセクタの次のセクタを読み込む処理。

シリンダ、ヘッド、セクタを指定して int 0x13 を呼び出す。
エラー発生時はCF=1となるので、その場合はエラーメッセージを表示する。

今日からイメージファイル名をtinyos.imgにした。
リンカスクリプトは変更なし。

Makefile

image_file=tinyos.img

ipl.bin: ipl.s lnk.ls
 gcc -nostdlib -o $@ -Tlnk.ls ipl.s
 gcc -Tlnk.ls -c -g -Wa,-a,-ad ipl.s > ipl.lst

zero.img:
# 1474560 - 512 = 1474048
 dd if=/dev/zero of=zero.img ibs=512 count=2879

image_file: ipl.bin zero.img
 cat ipl.bin zero.img > ${image_file}

img:
 make image_file

run:
 qemu-system-i386 -m 32 -localtime -vga std -fda ${image_file}

ipl.s

/*
 ipl.s
*/
 .code16
 jmp entry
 .byte 0x90
 .ascii "TINY_IPL" # ブートセクタの名前
 .word 512  # 1セクタのバイト数
 .byte 1  # クラスタの数
 .word 1  # FAT開始セクタ
 .byte 2  # FATの個数
 .word 224  # ルートディレクトリ領域のエントリ数
 .word 2880  # ドライブのセクタ数
 .byte   0xF0  # メディアタイプ
 .word 9  # FAT領域のセクタ数
 .word 18  # 1トラックのセクタ数
 .word 2  # ヘッド数
 .int 0  # ?
 .int 2880  # ドライブのセクタ数
 .byte 0, 0, 0x29 # ?
 .int 0xFFFFFFFF # ボリュームシリアル番号
 .ascii "TINY-OS    " # ディスクの名前
 .ascii "FAT12   " # フォーマットの名前
 .space 18

// プログラム
entry:
 movw $0, %ax
 movw %ax, %ss
 movw $0x7C00, %sp
 movw %ax, %ds

 // 2セクタから1セクタ分読み込む
 movw $0x0820, %ax
 movw %ax, %es
 movb $0, %ch  # シリンダ0
 movb $0, %dh  # ヘッド0
 movb $2, %cl  # セクタ2

 movb $0x02, %ah # ディスク読み込み
 movb $1, %al  # 1セクタ読み込む
 movw $0, %bx  # ES:BX Data buffer(0x8200に読み込む)
 movb $0x00, %dl # Aドライブ
 int $0x13  # BIOS interrupt call
 jc error

fin:
 hlt
 jmp fin

error: 
 movw $msg, %si
putloop:
 movb (%si), %al
 add $1, %si
 cmp $0, %al
 je fin  # メッセージの後ろの0x00で終了する
 movb $0x0E, %ah # Write Character in TTY Mode
 movw $15, %bx # カラーコード
 int $0x10  # BIOS interrupt call
 jmp putloop

// メッセージ 
msg: 
 .string "\n\nload error\n"

 .org 0x1FE
 .byte 0x55, 0xAA # 55AAでブートセクタ

$ make img
$ make run

で実行したが、エラーメッセージは出ていない。
指定したセクタを正しく読めているようであるが、本当にそうなのかは、画面からは分からない。

今日はここまで。