優先度スケジューリング実装完了 - 12ステップ本を試す その3

1/10に12ステップ本の著者の坂井さんが開催した第2回12ステップ本もくもく会に参加して依頼、あまり作業を進められていませんでした。先日の休みに数時間作業ができ、9章の優先度スケジューリングの実装まで終わったのでメモを残しておきます。

12ステップで作る組込みOS自作入門

12ステップで作る組込みOS自作入門

まず、8章。
この章ではスレッドの実装を行いますが、私の環境ではなぜかkz_thread構造体利用箇所で「kozos.c:(.text+0x173): undefined reference to `___mulsi3'
」というエラーがでてしまい、kz_thread構造体のパディングを行う必要がありました。
具体的には

typedef struct _kz_thread {
  struct _kz_thread *next;
  
  (省略)

  kz_context context;
  char dummy[16]; /* ←ここにpaddingを追加 */
} kz_thread;

こんな風にしました。

次に9章ですが、kz_thread構造体のサイズが変わったのでパディングのサイズも変える必要がありました。
下記のようにしています。

typedef struct _kz_thread {
  struct _kz_thread *next;
  
  (省略)

  kz_context context;
  char dummy[8]; /* ←9章ではpaddingは8に */
} kz_thread;

また9章ではOSをxmodemでロードするときに、OSのELFファイルの受信が「58ブロック/7K」で止まってしまうということが発生しました。
このサイズで受信が止まる、という症状だったのですぐに気づいたのですが、私は個人的にメッセージ出力を楽に書けるようにlib.cに独自にputmsg()という関数を書いたりするなど、いろいろ余計なものをkozosに追加していたためか、kozos.elfの大きさが8KBより少し大きくなってしまい、リンカ・スクリプトで当初用意していた受信バッファのサイズでは領域が足らなくなったのが原因でした。(→後日訂正追記:*1 )

これに対応するためにリンカスクリプト(ld.scr)でバッファのサイズを変更しました。バッファをメモリの前方方向に領域を広げるようリンカスクリプトを変更しています。
修正内容は下記の通りです。

  • 変更前
MEMORY
{
	(省略)
	buffer(rwx)	: o = 0xffdf20, l = 0x001d00
	(省略)
}
  • 変更後
MEMORY
{
	(省略)
	buffer(rwx)	: o = 0xffd280, l = 0x0029a0
	(省略)
}

bufferのオリジンは使われていない領域を確認して設定しました。
kozos.elfをreadelfコマンドで見てみると、プログラムヘッダが下記のようになっていたため、それに合わせてオリジンを調整しています。

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00ffbf8c 0x00ffbf8c 0x00e2e 0x00e2e R E 0x1
  LOAD           0x000e30 0x00ffcdbc 0x00ffcdbc 0x002a3 0x002a3 R   0x1
  LOAD           0x0010d4 0x00ffd060 0x00ffd060 0x00004 0x00220 RW  0x1

これをみるとkozosの使うメモリ領域の末尾が0xffd280番地(0x00ffd060 + 0x00220)なので、その直後からbufferが開始されるように設定しました。
bufferの末尾は以前のままになるようbufferの長さも0x002910に変更しました。


あと残り3章でこの本での組み込みOS開発の学習も終わりです。
次の休みに終わるよう頑張ろう。

*1:バッファの容量が不足していたのはstripコマンドを通していないkozos.elfを転送していたからでした。stripコマンドを通してシンボルテーブルを消したkozosファイルであれば6KBバッファ使用量はくらいで済みました