OS自作入門

OS自作入門
著 川合秀実

OS自作入門を読んだ感想です。
完全な理解ではないので、適当に書かれています。

MacOSXでやったので、以下を参考にしました。
http://d.hatena.ne.jp/sandai/20120728/p2
https://github.com/sandai/30nichideosjisaku

本書で不足してる部分はこちら
http://softwaretechnique.web.fc2.com/OS_Development/index.html


1日目

helloos.imgをバイナリエディタで書きます。
NASMというアセンブラを改良した筆者作のnaskというアセンブラでアセンブラ初体験。
バイナリエディタで書いたものをアセンブラ記述で18万行を超えるコードを書きます。(DB命令のみ)
RESB命令も使って省略出来る部分を省略し、22行にまとめたコードを書きます。
この時点では意味不明なソースコードなので、コメントやもう少し意味が分かりやすい命令を使って50行のコードを書きます。

セクタ:フロッピーディスクは512バイトずつまとめて読み書きするので、512バイトを1セクタと呼ぶ。フロッピーディスクは約1440kb、つまり2880セクタで構成される。
ブートセクタ:フロッピーディスクの最初のセクタのことで、PCはまず最初のセクタを読み、最後の2バイトを見ます。この2バイトが「55 AA」でなければ、起動に必要なプログラムではないと解釈されてしまう。
IPL:initial program loader。普通のOSはまずブートセクタを読み、最後の55 AAを確認した後、その最初のセクタでOS本体を読み込むプログラムが書かれている。OS本体を読み込むための初期プログラム読み込み機のことをIPLと呼ぶが、ブートセクタと考えてよい。

2日目

テキストエディタの紹介でTeraPadを紹介される。
レジスタの説明。
INT命令で使うBIOS関数(Basic Input Output System)の詳細
http://community.osdev.info/?(AT)BIOS
HLT命令について。
ORG命令の0x7c00とは一体何かの説明。アドレスがどういう風に割り振られているか。
http://community.osdev.info/?(AT)memorymap
ブートセクタが読み込むアドレスは既に決まっていて、0x00007c00 - 0x00007dffを読み込む。
Makefileの使い方について。
レジスタに[]をつけると、そのレジスタに代入されている数値のアドレスを参照する。

新出命令、単語
MOV命令
CMP命令
JE命令
INT命令:interrupt。ソフトウェア割り込み命令。BIOS関数の呼び出しと考えてよい。
HLT命令:halt。CPU停止命令。

3日目

ちゃんとしたIPLの作成。
フロッピーディスクの説明。
ここでは、0x8000以降のアドレスを使うことに。メモリマップで0x8000以降はあいてたので。
harib00aはブートセクタから次のセクタを読み込むように改良。読み込めなかったら失敗。
harib00bはすぐ失敗ではなく、エラー回数5回で失敗にするよう改良。
harib00cは18セクタまでどんどん読むように改良
harib00dは10シリンダまで読むように改良
harib00eは空のディスクに対してHLTだけ行うプログラムを書き込んだ際にどこのアドレスに書き込まれるのかを確認する
harib00fはブートセクタからOS本体のセクタへ飛んでOSを実行する。ブートセクタから一つ前に確認したアドレス(ブートセクタ分だけずらして)へ飛ぶ。
harib00gは画面モード切り替えで黒い画面の表示
harib00hは32bitモードへ準備。ここで16bitとはおさらばして、C言語が使えるようになるので、その前にやっておくべきことをしておく。画面モードに関する情報とキーボードの情報をメモリに書き込んでおく。
(AT)BIOSのページから0x0ff0番地周辺があいてるのを確認して使用。また画面モードは0x13(VGAグラフィックス、320x200x8bitカラー)を使っているので、VRAMは0xa0000~0xaffffの64kb。
harib00iは32bitモードへ移行し、本格的にC言語を導入。Makefileも強化。コンパイラについても説明。
harib00jはC言語からアセンブラを呼び出してC言語上でHLT命令を行う。

新出命令、単語
ヘッド:表の0と裏の1があり、表裏に書き込める
シリンダ:同心円上に0から79の80個の区分がされてるイメージ
セクタ:シリンダをさらに18個に区分している
フロッピーディスクの容量は2ヘッドx80シリンダx18セクタx512バイト=1440kb

4日目

VRAMのアドレスに書き込むことで、画面変化させる
harib01aはC言語からメモリアドレスに書き込む命令をアセンブリ側で作る
harib01bは画面をしましまに表示させる
harib01cはポインタを使うことでC言語のみでメモリアドレスに書き込ませる
char *p; //BYTE用番地
short *p; //WORD用番地
int *p; //DWORD用番地
これを指定してからp = (char *) i; *p = i & 0x0f;と書く
pはi番地の箱として、i番地にi & 0x0fを書き込む ということ
harib01dは*(p + i)という書き方を使っている
harib01eは配列を使う。配列p[i]は*(p + i)のシンタックスシュガー
harib01fは色の指定。普通24bitから色が選べるが、今回は8bitカラーモードなので、使う色8bit分のパレットを設定する
このパレットを設定する方法は、p88のパレットアクセス手順を参照。
この手順の中にある割り込みフラグをいじくるので、割り込みフラグ、EFLAGSの説明。
EFLAGSから数値を読み取る方法を実装。ついでにデバイスを操作するポート関連の関数も実装。
harib01gは図形の描写。320x200の座標に左上を(0, 0), 右下を(319, 199)としたとき、(x, y)のVRAMアドレスは0xa0000+x+y*320となる。
よって、0xa0000+x+y*320番地にパレット番号を記録することで、xy座標にそのパレット番号に対応する色が表示される。
harib01hはwindowsっぽくタスクバーを色の設定でつけた。

5日目

最終更新:2013年04月03日 22:30