30日でできる!OS自作入門を始めた[2日目]
半年ぶりの更新...。実は、もう本自体の内容はほとんどやってみたのだけれど、記事の更新が途中でとどまってからもう更新しなくなってしまっていた。
今回更新しようと思ったのは、僕が働かせてもらっている会社で自作OSの勉強会をしようということで、この本をやることになって、また1章から始めたのでせっかくだから復習も兼ねてまた記事の執筆に挑戦しようという志を持ったので。
ということで、久しぶりのOS自作入門スタート。
進行
ORG 0x7c00
ORG 0x7c00は、このプログラムがメモリのどこに読み込まれるかを示す疑似命令。 どうして0x7c00に読み込まれるかについては、以下の記事を見てなるほどなぁ。
https://www.glamenv-septzen.net/en/view/6
linuxのx86のアーキテクチャ依存の実装部分にも、0x7c00の文字がある。 https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S
そして、FAT12の使用に基づくヘッダがあって...
次にブートローダのプログラム本体。
初期化スべきレジスタを初期化して...
entry: MOV AX,0 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV ES,AX
msgのアドレスを、SIに入れて...
そうそう、自分は当初この本をやっていたときに
[SI]
の意味がよく分からなかった記憶があるのだが、これはSIに入っているアドレスのところに有るものを参照する、みたいなものだ。 メモリ参照とか言うらしい。
putloopは文字を1文字ずつ配置するサブルーチンだ。 実行の流れは次のとおりである。
- SIが指すメモリの中身をALに入れる
- SIに1を足して次のアドレスを指すようにする
- ALが0なら、文字列の最後なので比較して0ならfinのルーチンに飛ぶ
- 1文字の表示機能を指定するためAHに0x0eを入れる
- BXにカラーコードの番号を入れる
- 割り込みしてビデオBIOSというものを呼び出す
- putloopのアドレスに戻ってループ
putloopで代入した15というカラーコードだがこれは白色である。 使える色は以下の通り。16ビットだなーってかんじ。 https://en.wikipedia.org/wiki/BIOS_color_attributes
BIOSで使える機能と使い方がまとめられている http://oswiki.osask.jp/?(AT)BIOS
ところで、
INT 0x10
は割り込み命令だが、これで割り込みベクタの0x10番目のアドレスに飛ぶ、という仕組みらしい。 この本を始めた当初は割り込みベクタなんて知らなかったが、もう一つの自作OS本、坂井先生の本を読んで知った。
finルーチンではHLTをループしてCPUを停止させるだけ。
あとはMBRの規格構造に沿って埋めるだけ。
ところで、私はnaskではなくnasmを使ってアセンブルしているのでRESB命令がうまく使えなかった。なので、以下のように改めて書いた。
TIMES 0x1fe-($-$$) DB 0
疑問
entryでなぜSPを0x7c00に初期化するのか。0に初期化するなら分かる気がするが...何か仕様等で決まっているのだろうか。- 上の疑問についてだが、単に0x7c00から配置されるブートローダーの上が空いているので0x7c00に初期化されるというだけだった。考えてみれば、SPを0に初期化するというのは意味がない。スタックは零アドレスに向かって伸びるのだから。