OS学習メモ3(30日OS自作入門2-3日目)
OS学習の流れにのって30日本久々に読んでます。
この記事「OS本を持っていない人にもわかりやすく伝える」という感じではないです(微妙なところですが)。どちらかといえば進捗報告に近いのかなって思ってて、本読めばわかるようなところは説明まるごとすっ飛ばしたりします。時間があればガッツリ書きたかったんですがそうもいかないので…。
一日目
すっ飛ばし
二日目
新出命令
ORG: 続く命令をどこから格納するか、つまり先頭アドレスを指示する命令。
MOV:Cでいう代入みたいなもの。データをコピーする。
ADD:スペルそのまま、足し算する命令。
CMP:2つのオペランドを比較し、結果をEFLAGSのキャリーフラグ(後述)にセットする。ここではジャンプ命令と組み合わせて条件分岐に使った。
JMP:ジャンプ~。簡単ですね(ここ好きだったのでパクりました)
HLT:CPUを待機状態にさせる命令。
INT:割り込み命令。3日目のところで説明する。
参考:http://softwaretechnique.jp/OS_Development/Tips/IA32_Instructions/A.html
・汎用レジスタ(AX/BX/CX/DX)
何に使ってもいいレジスタ。頭文字がABCDになっていて覚えやすいけどこれは偶然で、それぞれAccmulator,Base,Counter,Dataの頭文字を取っている。何に使ってもいいとは言っても、AXは演算に,BXはメモリをの領域指定に,CXはカウンタ変数とかに,DXはI/O操作とかに使われることが一般的。
・特殊レジスタ(SP/BP)
用途が限られているレジスタで、それぞれStackとBaseの略。SPはスタック領域の一番上、BPはスタック領域の底を指す。確か後になって使うレジスタだったと思うのでここでの説明は省略。ちなみにここには登場していないがIP(Instruction Pointer)とかもあって、次に実行するアドレスを入れる。
・インデックスレジスタ(SI/DI)
SI (DI )は転送命令の転送元(先)を示すレジスタ。それぞれSourceとDestinationの略。
・セグメントレジスタ
(後で出てくる)
メモリ指定の話
MOV命令で、転送先/元にメモリを指定する場合は[ ]のかっこを使う。この時、かっこの前にBYTEやWORDなどの単語を指定することで、読み書きするデータの大きさも指定できる。
3日目
新出命令
ジャンプ系命令がいくつか
説明を保留してたINT命令
INTは割り込み用の命令。PCにはBIOS(Basic Input Output System)というプログラムがある。BIOSはPC起動時に最初に起動され、OSを起動するよりも前に(マウス,ディスクなどの)入出力装置を使用できる状態にしてくれたり、またそれらを制御する関数を提供している。INT命令はその関数を呼び出すために使う命令で、”INT 0x--”のように数字とセットで使われる。参考:http://oswiki.osask.jp/?(AT)BIOS
ディスク読み込み
AL,CH,CL,CH,DLに値を代入してディスクのどの部分を読み込むかを決定する。順に、処理するセクタ数,シリンダ番号,セクタ番号,ヘッド番号,ドライブ番号となっている。ちょうどよいところに数日前の記事で使った画像があったので再掲します
画像にない所を補足すると..".ヘッド番号"は上から磁気ヘッドを当てるか下から当てるかを0/1で指定するもので、"ドライブ番号"は…とりあえず0を指定しておけば良い。
バッファアドレス
メモリのどこに読み込むかを表す番地のこと。これをBXレジスタ(16bit)だけを使って表そうとすると、0-0xffff(およそ64KB)までの領域しか表せないので、もっと多くの番地を指定しようということでセグメントレジスタ(ES/CS/SS/DS/FS/GS)が使われた。ES:BXという表現がまさにそれで、この場合はES*16+BX番地を指定していることになる。
ここまでがIPLの説明。
ここからOS本体に入る
まずHLTをつかったプログラム(haribote.s)を作成して、ディスクイメージに保存する。それをバイナリエディタで観察すると「空の状態のディスクにファイルを保存するとファイル名は0x002600以降に入ること」と「ファイルの中身は0x004200以降に入ること」の2つがわかる.........らしい。
早速自分でも試してみようと思ったんですが、本とは環境が大分違うので結構調べることになりました。結論から言うと「それっぽいことはできたが確信が持てない」って感じです。..まぁとりあえず載せます。
まず準備としてharibote.nasを用意
アセンブルして実行形式のharihariというのを作った。
nasm -f bin haribote.nas -o harihari
準備ができたらまず「Finder→アプリケーション→ユーティリティ→ディスクユーティリティ」を開いて、空のイメージを作成して(この時「サイズ:1440KB」「パーティション:パーティションマップなし」「フォーマット:MS-DOS(FAT)」に変更する)、作成したディスクイメージの中にHLTのプログラムを普通に置く
そしたらまた同じようなディスクイメージを、今度は別の場所に作る(画像ではデスクトップに作ってたのでそれ以外の場所に)。作り終えたらディスクユーティリティの画面に戻り、2回目に作ったディスクを選択して「復元→復元元で1回目のディスクイメージ選択」を実行する。そうして出来上がったものをバイナリエディタ(自分は0xED)で開いて中身を見てみた。
たしかにファイル名は0x002600以降にあるなという感じだが、F4 EB FDは0x007A00のところに来てる(っていうか目grepでこれ見つけるのほんと大変だった)。まぁ...理由はわかんないけどそんなに大きな違いとかはなさそう(?)
...ブートセクタの先頭がメモリの0x8000番地だったら...この0x7A00の部分はメモリの0x00FA00に読み込めているということなんだろうか?ならばharibote.nasに"ORG 0x00FA00"を付け加えて、ipl.nasの最後には"JMP 0x00FA00"を付け加えて...。
ってやって、そのちょっと先の方まで読み進めたが、なかなか実行までたどり着けずかれこれ4,5時間は格闘した。そして格闘した結果諦めることにした...ほんとに悔しい。自力では無理だったのでここからは先人が用意してくれた方法を使って先に進みます。
環境を整えて実行し...
おぉ...すごい...ちゃんと動いてる...。
今回はここまで。正直めちゃくちゃ疲れました...