30日OS自作本3日目
なんかすごく低レイヤー臭が強まったdayでした。
フロッピーの容量は次のように決まる
- 1セクタ=512バイト
- 1シリンダ=18セクタ
- 1面あたりのシリンダ数=80シリンダ
- ヘッドの数(つまり面の数):2面(両面)
512バイト × 18セクタ × 80シリンダ × 2 = 1474560B ≒ 1.440KB
トラックとシリンダの意味で混乱したのでteratailで聞いて見ました。
記憶装置のトラックとかシリンダとかは情報処理試験を受けるたびに理解せずに暗記して忘れるということを繰り返しましたが、今度はしっかり覚えれた気がします。
ESとBXレジスタを使ったバッファアドレスの決まり方
BX = 16ビット = 2^16-1 = 65,535
EBX = 32ビット = 2^32-1 = 4,294,967,295
16bitのBXレジスタだけだと64KBしか表せないが、EBXレジスタは4GBまで表せる。が、EBXレジスタが導入されるのは、BXだけじゃ足らん!となってからもっと後のこと。ではBXで足りなくなってからどうやって凌いだかというと。。。16bitのセグメントレジスタであるES(エクストラセグメント)とBXの合わせ技で解決した。
ES * 16 + BXレジスタ
で番地を指定する。
これで((2^16-1) * 16) + 2^16-1 =1,114,095バイト
(およそ1MB)まで指定できるようになった。
セグメントレジスタはBX以外のレジスタを使うときも考慮されるらしくどのセグメントレジスタを使うか指定する必要がある。省略するとDSが選ばれるらしい。だからDSは基本的に0で初期化しないと16の倍数分ブーストされた思わぬアドレスに遭難する恐れがある。
BIOSとのお別れ
32ビットモードを使う以上、16ビットで動いているBIOSとはお別れ。 なおC言語を導入することでnaskを使ってアセンブラ(nas) -> バイナリ(img)で済ませていた手順から大きく変更が入る。
手順 | 使うツール | やること |
---|---|---|
1 | cc1.exe | .c -> .gas |
2 | gas2nask | .gas -> .nas |
3 | nask | .nas -> .obj |
4 | obj2bim | .obj -> bim |
5 | bim2hrb | .bim -> hrb |
6 | cat | .bon + hrb でバイナリをくっつける |
実際にmakeした時のコマンドにコメントを入れて対応関係を見てみる。 今までは手順3だけでよかったのに途端にやることが増える*1
$ make run make -r img make -r haribote.img ../../z_tools/nask ipl10.nas ipl10.bin ipl10.lst ../../z_tools/nask asmhead.nas asmhead.bin asmhead.lst ../../z_tools/gocc1 -I../../z_tools/haribote/ -Os -Wall -quiet -o bootpack.gas bootpack.c #⚠️1 ../../z_tools/gas2nask -a bootpack.gas bootpack.nas #⚠️2 ../../z_tools/nask bootpack.nas bootpack.obj bootpack.lst #⚠️3 ../../z_tools/obj2bim @../../z_tools/haribote/haribote.rul out:bootpack.bim stack:3136k map:bootpack.map \ bootpack.obj #⚠️4 ../../z_tools/bim2hrb bootpack.bim bootpack.hrb 0 #⚠️5 cat asmhead.bin bootpack.hrb > haribote.sys #⚠️6 ../../z_tools/edimg imgin:../../z_tools/fdimg0at.tek \ wbinimg src:ipl10.bin len:512 from:0 to:0 \ copy from:haribote.sys to:@: \ imgout:haribote.img cp haribote.img ../../z_tools/qemu/fdimage0.bin make -r -C ../../z_tools/qemu qemu-system-i386 -L . -m 32 -localtime -vga std -fda fdimage0.bin WARNING: Image format was not specified for 'fdimage0.bin' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions.
個人的には手順6が結構衝撃的。naskで作ったバイナリ(asmhead)にbim2hrbで作ったバイナリをくっ付けてるだけ。
ファイルサイズを確認したけど304+52=356
で確かに一致する。
$ls -l total 3072 -rw-r--r-- 1 staff 304 5 5 11:52 asmhead.bin -rw-r--r-- 1 staff 52 5 5 11:52 bootpack.hrb -rw-r--r-- 1 staff 356 5 5 11:52 haribote.sys
手順3で普通にnask使ってるけどここでアセンブルされたobjファイルと手順4,5を通して出来た.hrbファイルの質的な違いがいまいちわからない。
う〜ん。まぁとりあえず進めましょう。
新しく知ったこと
gccはgasというアセンブリ用のソースを出力する
GDBを使ったC言語のデバッグは昔こちらの本でちょっとだけやったことがあったのですが、
Hacking: 美しき策謀 第2版 ―脆弱性攻撃の理論と実際
- 作者: Jon Erickson,村上雅章
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/10/22
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 163回
- この商品を含むブログ (19件) を見る
gccというコンパイラはgasという名称のアセンブラを前提にしているので、gas用のソースプログラムを出力してしまうのです。
普通にgccってx86とかが実行できる機械語のコードを作ると思っていたのですが、gasというのは初見。*2
c -> x86の命令コード
くらいに思っていたのですが、この矢印の間にgasとか、まだ他にも何かが何個か入るのかもしれません。
objファイルのobjectは目的、の意味
オブジェクトというのは「object」、つまり目的のことです。私たちは機械語を得るためにC言語プログラムを書いているわけで、これを目的ファイルと呼ぶのはそこに由来しています。
へぇ〜そうだったのかobjectって普通に物体とかモノとかそういう感じの意味でつけてるのだと思ってました。
- 作者: 川合秀実
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2006/03/01
- メディア: 単行本
- 購入: 36人 クリック: 735回
- この商品を含むブログ (299件) を見る