30日OS自作本22日目2hrbファイルの構造
.hrbファイルの構造とcmd_app()の改善
アプリケーションから利用できる文字表示APIを作ったところ、C言語から作ったアプリケーションでは データ(文字列)の取得がうまくいかないようです。本章では.hrbファイルの解説と件のデータ取得の改善が解説されています。
hrbファイルの解説
hrbファイルはそもそもharibote OSのオリジナルの実行ファイルです。 本章で多分はじめてhrbファイルの仕様が公開されます(多分)
- 0x0000,OSに用意してもらうアプリ用のデータセグメントの大きさ
- 0x0004,"Hari"(.hrbファイルであることのマーク)
- 0x0008,データセグメント内の予備領域の大きさ
- 0x000C,ESPの初期値&データ部分の転送先番地
- 0x0010,hrbファイル内部のデータ部分の大きさ
- 0x0014,hrbファイル内にあるデータ部分がどこから始まっているのか
- 0x0018,0xe90000000
- 0x001c,アプリの実行開始番地 - 0x20
- 0x0020,malloc領域開始アドレス
hello4.hrbの例
00000000 00 10 00 00 48 61 72 69 00 00 00 00 00 04 00 00 |....Hari........| 00000010 0e 00 00 00 64 00 00 00 00 00 00 e9 39 00 00 00 |....d.......9...| 00000020 10 04 00 00 55 89 e5 68 00 04 00 00 e8 13 00 00 |....U..h........| 00000030 00 58 c9 e9 1a 00 00 00 ba 01 00 00 00 8a 44 24 |.X............D$| 00000040 04 cd 40 c3 53 ba 02 00 00 00 8b 5c 24 08 cd 40 |..@.S......\$..@| 00000050 5b c3 ba 04 00 00 00 cd 40 55 89 e5 5d e9 c2 ff |[.......@U..]...| 00000060 ff ff 00 00 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 |....hello, world| 00000070 0a 00 |..|
hello4.hrbのデータと対応づけてみました。
addr | data |
---|---|
0x0000 | 0x00100000 |
0x0004 | 0x48617269 |
0x0008 | 0x00000000 |
0x000C | 0x00040000 |
0x0010 | 0x0E000000 |
0x0014 | 0x64000000 |
0x0018 | 0x000000E9 |
0x001c | 0x39000000 |
0x0020 | 0x10040000 |
0x0024 | 0x5589E568 |
例えば
addr | data |
---|---|
0x0014 | 0x64000000 |
0x0014,hrbファイル内にあるデータ部分がどこから始まっているのか
ですが、hello4.hrb
ファイルの0x64の位置からhello, world
のデータが格納されているのがわかります。
またdの書かれているアドレスが0x64+0xE=0x72
であり、ファイル終端までがデータという扱いにしていることもわかります。
コマンド用の実行ファイルをCのソースから作る際、文字列がうまく参照できないようになっているようです。それをこちらのファイルフォーマットを参考に、cmd_app関数で、0x0014
の位置に格納されている文字データをこのような感じでセグメント内ESP(0x000C
)のスタックに転送しています。
/* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo->size); ・・・中略・・・ esp = *((int *) (p + 0x000c)); //ESPの初期値&データ部分の転送先番地 dathrb = *((int *) (p + 0x0014)); //hrbファイル内にあるデータ部分がどこから始まっている ・・・中略・・・ q = (char *) memman_alloc_4k(memman, segsiz); for (i = 0; i < datsiz; i++) { q[esp + i] = p[dathrb + i]; }
また.hrbファイルから得られる情報であるセグメントサイズの大きさ、データ部分の大きさもOSの改善に役立てています。
datsiz = *((int *) (p + 0x0010)); //hrbファイル内部のデータ部分の大きさ segsiz = *((int *) (p + 0x0000)); //OSに用意してもらうアプリ用のデータセグメントの大きさ
セグメントは今まではとりあえず64KBとなっていますが、こちらを参照することでセグメントの利用効率が上がります。
//.hrbファイル中のセグメントサイズを使うように改善。 //q = (char *) memman_alloc_4k(memman, 64 * 1024); q = (char *) memman_alloc_4k(memman, segsiz);
感想
アプリケーションのデータを参照するために、なぜこのような手間がかかるのか理解できませんでした。著者の自作ツール(bim2hrb)を利用されていない方のブログなどを見ると特にこの作業は不要そうです。bim2hrb等は普通のリンカに必要とされる何かが抜けているのでしょうか?まぁ私リンカがなんたるかもそんなにわかっていないので特にこの辺を探求するのはまだ早いかなと思いました。
次回はウインドウAPIについてです。