HDD
QEMU
アセンブリ言語
OS

30日でできる!OS自作入門(QEMU上で、HDDから読み込みしてみた)

30日でできる!OS自作入門(寄り道)

三日目まで来たところで、寄り道をしているところです…

バッチファイルの勉強やQEMUの使い方や、QEMU上でFDではなくHDDから起動を試してみたりと。。

とりあえず今回は、HDDから起動する方法を紹介したいと思います。

QEMU上で、HDDから起動してみた

開発環境は、

NASK(30日でできる!OS自作入門で用意されているアセンブリ言語)

QEMU

dd コマンド(Windows用)

qemuで試す。

ファイルは以下です。


helloos.nas

ORG 0x7c00

JMP entry
db 0x90

entry:
MOV AX, 0 ;必要なレジスタを初期化
MOV DS, AX
MOV ES, AX

MOV AH, 0x02 ;読み込みモード
MOV AL, 1
MOV CH, 0
MOV CL, 2
MOV DH, 0
MOV DL, 0x80 ;ブート可能なHDDのドライブ番号は0x80のみらしい……
MOV ES:BX, 0x7e00 ;バッファアドレスは0x7e00番地から用意
INT 0x13
JC error
JMP 0x7e00 ;次のセクタは0x7e00番地から読み込まれる

error: ;これ以降はエラー処理の部分なので省略
MOV AX, 0
MOV AH, 0x13
MOV AL, 0x00
MOV BH, 0
MOV BL, 15
MOV CX, 7
MOV DL, 0x10
MOV DH, 0x10
MOV ES:BP, msg
INT 0x10
JMP fin

fin:
HLT
JMP fin

msg:
db "error!!"

RESB 0x7dfe-$
DB 0x55, 0xaa



sector2.nas

ORG 0x7e00

MOV AX, 0 ;必要なレジスタを初期化
MOV DS, AX
MOV ES, AX

MOV AH, 0x13 ;msg番地から始まる文字列を表示
MOV AL, 0x00
MOV BH, 0
MOV BL, 15
MOV CX, 9
MOV DL, 0x10
MOV DH, 0x10
MOV ES:BP, msg
INT 0x10
JMP fin

fin:
HLT
JMP fin

msg:
db "success!!"

RESB 0x8000-$ ;一つのセクタが書き込まれる必要があるので残りは0


ファイルを二つ用意しました。

helloos.nasはUSBの先頭のセクタのファイルです。

sector2.nasはブートセクタの次のセクタのファイルです。

helloos.nasをアセンブルして、helloos.imgを作ったあと、

sector2.nasをアセンブルして、ddコマンドhelloos.imgの512byte以降に書き出しました。

ddのコマンドは



dd if=sector2.bin of=helloos.img bs=512 count=1 seek=1



とすることで、sector2.binをhelloos.imgに書き加えることができます。

qeumuで上のhelloos.imgを起動した結果が下になります。

image.png

success!!と表示されているので、成功です。

また、HDDから起動していることも

Booting from Hard Diskから見て取れます。

アセンブリファイルの解説をしようと思います。

hellooc.nasの読み込みモードが特に重要なのでここを説明します。


helloos.nasのHDDからの読み込みの部分

    MOV AH, 0x02        ;読み込みモード

MOV AL, 1
MOV CH, 0
MOV CL, 2
MOV DH, 0
MOV DL, 0x80 ;ブート可能なHDDのドライブ番号は0x80のみらしい……
MOV ES:BX, 0x7e00 ;バッファアドレスは0x7e00番地から用意
INT 0x13
JC error
JMP 0x7e00 ;次のセクタは0x7e00番地から読み込まれる


MOV AH, 0x02からMOV DH, 0までの命令はフロッピーディスクでも使う命令です。ここまでの行はHDDでも同じです。

次の命令のMOV DH, 0x80はフロッピーディスクと異なります。ここは、ドライブ番号を指定するところで、

フロッピーディスクの場合は0x00と0x01ですが、HDDの場合は、0x80以降になります。

そして、起動デバイスの場合は、0x80を指定しないといけません。ここを0x81などにすると、

起動できなくなるので注意です。

MOV ES:BX, 0x7e00はHDDからのデータをRAMのどこに読み込むのかを指定する部分です。

0x7e00と指定したので、RAMの0x7e00番地からデータが展開されることになります。

INT 0x13は割り込み命令です。0x13と指定することで、ディスクに関する割り込みと指定します。

JC命令については、INT 0x13でエラーが起きたとき、CFに1を立てるようなので、

CF==1のとき、指定した番地に飛べというJCをここに書きました。

次にJMP 0x7e00はHDDのデータを0x7e00に読み込んだので、その番地に飛べという命令です。これで読み込んだHDDのデータの命令を実行することができます。

なぜ、私は、0x7e00番地を指定したかというと、0x7dffまでは、ブートセクタが使っているので、その次の番地から使うことにしました。

sector2.nasは

ORG 0x7e00というところ以外、目立ったものはありません。