Yabu.log

ITなどの雑記

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についてです。