													TOPPERS Confidential
		TOPPERSプロジェクト 設計メモ
		メモリオブジェクトのコンフィギュレーション手順

		作成者: 高田広章（名古屋大学）
		最終更新: 2013年2月4日

○メモの位置づけ

このメモは，HRP2カーネルにおけるメモリオブジェクトのコンフィギュレーショ
ン手順の設計に関してまとめたものである。ATK2-SC3のコンフィギュレーショ
ン手順も，可能な限りこれを踏襲して設計されている。

○前提

・リンカによる最適化は考慮しないこととする
	- オブジェクトモジュールを生成した時点で，サイズが決まること
	- ただし，エラーチェックは行う（リンカが最適化したらエラーになる）

○準備

HRP2カーネルが管理するメモリオブジェクトは，どのように配置を決定するか
によって，次のように分類することができる。

(1) コンフィギュレーションにおいて配置を決定する

以下の(2)に該当するメモリオブジェクトを除くほとんどのメモリオブジェクト
の配置は，コンフィギュレーションにおいて，ツールによって決定される。以
下では，これに該当するメモリオブジェクトを，自動配置されるメモリオブジェ
クトと呼ぶ。

実際には，ターゲット依存で，リンカが配置を決定する場合（多くのターゲッ
トが該当）と，コンフィギュレータが配置を決定する場合（ARM MPUの場合な
ど，以下で述べる発展的な要求(a)に対応した場合）がある。

(2) ユーザが配置するアドレスを指定する

ユーザが，メモリオブジェクトを配置するアドレスを指定する。HRP2カーネル
では，次の2つがこれが該当する。

　・ATT_MEM／ATA_MEMによって登録されたメモリオブジェクト
　・CRE_TSKによって先頭番地を指定されたユーザスタック領域

これらのメモリオブジェクトの先頭番地は，静的APIにおいて，一般定数式パラ
メータとして指定する。そのため，配列により確保し，その配列名により先頭
番地を指定するユースケースもある。このような場合，間接的にはツールが配
置を決定していることになる。

以下では，これに該当するメモリオブジェクトを，指定配置されるメモリオブ
ジェクトと呼ぶ。

○基本的なコンフィギュレーション手順

(1) コンフィギュレータ パス1

・パラメータ計算用C言語ファイル（cfg1_out.c）の生成
	- 条件ディレクティブにより有効になる静的APIの判別
	- 静的APIの整数定数式パラメータの値の算出
・文法エラーや未サポートの記述の検出

(2) パラメータ計算用C言語ファイルのコンパイル

この段階で決定されるもの
	- 条件ディレクティブにより有効になる静的API
	- 静的APIの整数定数式パラメータの値

(3) コンフィギュレータ パス2

・カーネル構成・初期化ファイル（kernel_cfg.c）の生成
・カーネル構成・初期化ヘッダファイル（kernel_cfg.h）の生成
・仮のメモリ構成・初期化ファイル（kernel_mem2.c）の生成
・仮のリンカスクリプト（cfg2_out.ld）の生成
	- 最終的なリンカスクリプトとの違いは，kernel_mem.oをリンクする代わ
	  りに，kernel_mem2.oをリンクすることのみ
・静的APIの整数定数式パラメータの不正エラーの検出

この段階で最終的なメモリ構成・初期化ファイルを生成できないのは，この段
階では，メモリオブジェクトのサイズや配置アドレスがわからないためである。
配置アドレスがわからないと，メモリオブジェクト初期化ブロックを先頭番地
の小さい順にソーティングすることができない。また，サイズがわからないと，
サイズが0のメモリオブジェクトの初期化ブロックを生成しないようにできない。

(4) アプリケーションのロードモジュール2の生成

この段階で決定されるもの
	- すべてのメモリオブジェクトのサイズ
	- すべてのメモリオブジェクトの配置アドレス

(5) コンフィギュレータ パス3

・メモリ構成・初期化ファイルの生成を阻害するエラーの検出
	- 指定配置したメモリオブジェクトのオーバーラップのチェックを含む
・メモリ構成・初期化ファイル（kernel_mem.c）の生成
	- kernel_mem.oのサイズは，kernel_mem2.oと同じであること
・リンカスクリプト（ldscript.ld）の生成
・静的APIの一般定数式パラメータの不正エラーの検出

(6) アプリケーションのロードモジュール3の生成

(7) アドレスが変わっていないことのチェック

・ロードモジュール2と3のシンボルファイルのdiffを取ることで実施
	- これにより，想定したアドレス配置になっていることが保証される

〔考察〕

静的APIの一般定数式パラメータの不正エラーの検出がパス3で実施できるのは，
次の理由による。

ロードモジュール2の生成の時点で，すべてのメモリオブジェクトの配置アドレ
スとサイズが決定される。つまり，すべてのシンボルの値も決定されるため，
静的APIの一般定数式パラメータの値もこの時点で決定される。

○コンフィギュレーション手順に対する発展的な要求

上記の基本的なコンフィギュレーション手順では対応できない発展的な要求と
して，次の2つがある。

(a) メモリオブジェクトの配置をコンフィギュレータで決定したい
	- ARM MPUの場合に必要

(b) kernel_mem.oのサイズを適正化したい
	- メモリオブジェクト初期化ブロックの領域（memtop_table，meminib_table）
	  のサイズの適正化
	- data/bssセクション初期化のためのデータ構造（datasecinib_table，
	  bsssecinib_table）のサイズの適正化
	- MMUのページテーブル領域のサイズの適正化

●要求(a)への対応方法に関する検討

ここでは，要求(a)に対応するための方法について検討する。

コンフィギュレータによるメモリオブジェクトの配置の決定は，メモリオブジェ
クトのサイズが決まってから行う必要があるため，ロードモジュール2の生成後
のパス3で実施することが必要である。基本的手順のパス3は，メモリオブジェ
クトの配置アドレスが決まってから行う必要があるため，要求(a)に対応した場
合にはパス4として実施する必要がある。

つまり，要求(a)に対応するためには，コンフィギュレータのパスを1つ増やす
必要がある。

この時，指定配置されるメモリオブジェクトのアドレスも，パス2で決定される
とは限らないことに留意する（ATT_MEM等で指定された先頭番地が整数定数式で
あれば，ロードモジュール2の生成時点でアドレスが決まる。しかし，他のセク
ションの配置アドレスに依存する式や，LNK_SECにより登録したセクション内の
アドレスを指定した場合には，この段階で決定されない）。

●要求(b)への対応方法に関する検討

ここでは，要求(b)に対応するための方法について，要求(a)への対応とは独立
に検討する。

kernel_mem.oのサイズを適正化するには，各データ構造の適切なサイズを知る
必要があるが，これを知ることができるのは，コンフィギュレータのパス3であ
る。そこで，ロードモジュール2における各メモリオブジェクトのサイズを，パ
ス3での適正化処理の影響を考慮して補正することで，各メモリオブジェクトの
最終的なサイズを算出できるように思われる。

しかし，プログラム中にアラインメント制約のあるメモリ領域が含まれている
と，データ構造のサイズを小さくした量と，メモリオブジェクトのサイズが小
さくなる量が，一致するとは限らない。例えば，サイズを適正化したいデータ
構造の後ろに8バイト単位でアラインすべきメモリ領域があると，データ構造を
4バイト小さくした場合に，メモリオブジェクトのサイズが小さくならない場合
と，8バイト小さくなる場合がある（データ構造は4バイト単位でアラインされ
ると仮定）。

このことから，サイズ適正化後の各オブジェクトモジュールの正確なサイズは，
ロードモジュール3を生成した時点で決定し，コンフィギュレータのパス4では
じめて知ることができる。

〔備考〕

発展的な要求(b)に対応する場合でも，メモリオブジェクト初期化ブロックの余
分な領域を全くなくすことはできない。この理由は次の通り。自動配置される
メモリオブジェクトと指定配置されるメモリオブジェクトが隣接して配置され
るかは，すべてのメモリオブジェクトの配置アドレスが決定されるまで判断で
きない。そのため，メモリオブジェクト初期化ブロックはそれらが隣接されな
いものとして確保するしかなく，隣接した場合は余分な領域が生じるのは避け
られない（余分な領域を全くなくすには，決定順序が循環してしまう）。

●要求(a)と要求(b)の両方に対応する方法に関する検討

要求(a)と要求(b)の両方に対応するためには，kernel_mem.oのサイズ適正化後
の各オブジェクトモジュールの正確なサイズが決定できた後に，コンフィギュ
レータによるメモリオブジェクトの配置の決定を行う必要がある。つまり，配
置の決定はコンフィギュレータのパス4で行い，ロードモジュール4を生成し，
さらにコンフィギュレータのパス5の実行と，ロードモジュール5の生成を必要
とする。

○現バージョン（Release 2.1.0）での対応

現バージョンでは，要求(a)と要求(b)は同時に実現できないという制約を設け，
コンフィギュレータの実行をパス4までに抑えるアプローチを採っている。

以下では，各方式を区別するために，次の変数を用いる。

USE_CFG_PASS3：パス3を使う（いずれかの発展的な要求に対応する）場合に真
となる変数。

USE_CFG_PASS3_RELOCATE：パス3でメモリオブジェクトの配置を決定する（発展
的な要求(a)に対応する）場合に真となる変数。

USE_CFG_PASS3_RESIZE：パス3でメモリオブジェクトのサイズを変更する（発展
的な要求(b)に対応する）場合に真となる変数。

上に述べた制約により，USE_CFG_PASS3_RELOCATEとUSE_CFG_PASS3_RESIZEが同
時に真になることはない。

また，USE_CFG_PASS3_RELOCATEとUSE_CFG_PASS3_RESIZEの区別はターゲット非
依存部には影響がないため，これらの変数はターゲット非依存部には導入しな
い。

〔考察〕

2つの発展的な要求を同時に達成したい場合，発展的な要求(b)をパス3で，発展
的な要求(a)をパス4で実施し，パス5で最終的なkernel_mem.oを生成する方法が
考えられる。2つの発展的な要求を同時に達成したい要求が強い場合，将来のバー
ジョンで，このアプローチを採用する可能性もある。

●現バージョンでのコンフィギュレーション手順

(1)〜(2)は基本手順と同様

(3) コンフィギュレータ パス2

・カーネル構成・初期化ファイル（kernel_cfg.c）の生成
・カーネル構成・初期化ヘッダファイル（kernel_cfg.h）の生成
・仮のメモリ構成・初期化ファイル（kernel_mem2.c）の生成
・仮のリンカスクリプト（cfg2_out.ld）の生成
	- 最終的なリンカスクリプトと違い，kernel_mem.oをリンクする代わりに，
	  kernel_mem2.oをリンクする
	- USE_CFG_PASS3の場合には，その他に違いがあってもよい
・静的APIの整数定数式パラメータの不正エラーの検出

(4) アプリケーションのロードモジュール2の生成

この段階で決定されるもの
　［USE_CFG_PASS3でない場合］
	- すべてのメモリオブジェクトのサイズ
	- すべてのメモリオブジェクトの配置アドレス
　［USE_CFG_PASS3_RELOCATEの場合］
	- すべてのメモリオブジェクトのサイズ
　［USE_CFG_PASS3_RESIZEの場合］
	- 内容が空のメモリオブジェクト／セクション（がどれであるか）

(5) コンフィギュレータ パス3［USE_CFG_PASS3の場合のみ］

［USE_CFG_PASS3_RELOCATEの場合］
・自動配置されるメモリオブジェクトの配置アドレスの決定
・仮のメモリ構成・初期化ファイルの生成を阻害するエラーの検出
・仮のメモリ構成・初期化ファイル（kernel_mem3.c）の生成
	- kernel_mem3.oのサイズは，kernel_mem2.oと同じであること
・仮のリンカスクリプト（cfg3_out.ld）の生成
	- 最終的なリンカスクリプトとの違いは，kernel_mem.oをリンクする代わ
	  りに，kernel_mem3.oをリンクすることのみ

［USE_CFG_PASS3_RESIZEの場合］
・仮のメモリ構成・初期化ファイルの生成を阻害するエラーの検出
・仮のメモリ構成・初期化ファイル（kernel_mem3.c）の生成
	- この段階で，kernel_mem.oのサイズを適正化する
	- kernel_mem3.oのサイズは，kernel_mem2.oと違っていても良い
・仮のリンカスクリプト（cfg3_out.ld）の生成（オプション）
	- 最終的なリンカスクリプトとの違いは，kernel_mem.oをリンクする代わ
	  りに，kernel_mem3.oをリンクすることのみ

・コンフィギュレータの実行後に，cfg3_out.ldが生成されていない場合には，
　次の手順で生成する。
	- cfg2_out.ld中の"kernel_mem2.o"を"kernel_mem3.o"に置換する

(6) アプリケーションのロードモジュール3の生成［USE_CFG_PASS3の場合のみ］

この段階で決定されるもの
	- すべてのメモリオブジェクトのサイズ
	- すべてのメモリオブジェクトの配置アドレス

(7) コンフィギュレータ パス4

・メモリ構成・初期化ファイルの生成を阻害するエラーの検出
	- 指定配置したメモリオブジェクトのオーバーラップのチェックを含む
・メモリ構成・初期化ファイル（kernel_mem.c）の生成
	- kernel_mem.oのサイズは，USE_CFG_PASS3の場合はkernel_mem3.oと，そ
	  うでない場合はkernel_mem2.oと同じであること
・リンカスクリプト（ldscript.ld）の生成（オプション）
・静的APIの一般定数式パラメータの不正エラーの検出

・コンフィギュレータの実行後に，ldscript.ldが生成されていない場合には，
　次の手順で生成する。
	- cfg3_out.ldがある場合には，cfg3_out.ld中の"kernel_mem3.o"を
	  "kernel_mem.o"に置換する
	- そうでない場合には，cfg2_out.ld中の"kernel_mem2.o"を
	  "kernel_mem.o"に置換する

(8) アプリケーションのロードモジュール4の生成

(9) アドレスが変わっていないことのチェック

・ロードモジュール3と4のシンボルファイルのdiffを取ることで実施
	- これにより，想定したアドレス配置になっていることが保証される

●各パスのテンプレートファイルの名称

コンフィギュレータの各パスのテンプレートファイルの名称は，次の通りとす
る。

パス2：
	ターゲット依存部：target.tf，ターゲット非依存部：kernel.tf

パス3：
	ターゲット依存部：target_opt.tf，ターゲット非依存部：kernel_opt.tf

パス4：
	ターゲット依存部：target_mem.tf，ターゲット非依存部：kernel_mem.tf

ASPカーネルのパス3のテンプレートファイルの名称（ターゲット依存部：
target_check.tf，ターゲット非依存部：kernel_check.tf）は，HRP2カーネル
では用いない。

●要求(a)に対応する際の制限/留意事項

ソースプログラム中に明示的にアラインメント指定がされていると，メモリオ
ブジェクトのアドレス配置の変更により，メモリオブジェクトのサイズが変わ
る場合が考えられる。例えば，4KB境界へのアラインすべきメモリ領域を2KB境
界（4KB境界ではない）に配置すると，2KBの隙間ができるために，4KB境界に配
置した場合とサイズが異なってしまう。

この問題は，ロードモジュール2において，明示的に指定されるアラインメント
単位以上の単位でメモリオブジェクトを配置しておくことで，回避することが
できる。このようは配置は，パス2における仮のリンカスクリプトの生成時に，
明示的に指定されるアラインメント単位の最大値を与えることで実現できる。
ただし，このようにアラインすることで，メモリ不足が起こる可能性があり，
ロードモジュール2においてはメモリサイズを拡大しておく必要が考えられる。

○他の対応案

指定配置されるメモリオブジェクトの先頭番地の指定方法を制限して，簡略化
を目指す案が考えられる。

具体的には，指定配置されるメモリオブジェクトの先頭番地として，整数定数
式パラメータしか指定できなくする方法が考えられる。この方法で，ATT_MEMは
困らないと思われるが，CRE_TSKのユーザスタック領域がこれで良いかは悩まし
い。LNK_SECを廃止して，タスクのスタック領域共有の方法を見直すなどの仕様
見直しが必要である。

この案は，CRE_TSKのパラメータをASPカーネルとできる限り互換にしようとす
る方針と反することから，採用しないこととした。

以上
