													TOPPERS Confidential
		TOPPERSプロジェクト 設計メモ
		GNUリンカに関するメモ

		作成者: 高田広章（名古屋大学）
		最終更新: 2011年12月31日

○メモの位置付け

このメモは，TOPPERS/HRP2カーネルの開発のために作成したGNUリンカに関する
メモである．

このメモは，GNUリンカのマニュアルおよび以下のバージョンのGNUリンカの動
作を調査することによって作成したものである．

	arm-none-eabi-ld
	GNU ld (GNU Binutils) 2.19.51.20090709

異なるバージョンのGNUリンカは異なる動作をする可能性があるため，注意する
こと．

○TIPS

●セクションの調査方法

objdumpに-hオプションを付けることで，各セクションのサイズ，VMA，LMA等を
調べることができる．

○LMA指定の有効範囲

セクションのLMAを一度変更すると，後続のセクションにもそれが引き継がれて
しまう（リンカスクリプトの文法からは，引き継がれないように見える）．こ
れは，「AT(<LMAアドレス>)」についても，「AT > <リージョン>」についても
同様である．ただし，「AT > <リージョン>」については，この現象が起こって
いないと思われる報告もある．

そのため，LMAを変更したセクションの後に，LMAとVMAが一致するセクションを
配置する場合には，LMAを元に戻す記述を明示的に入れる必要がある．

○LMA側に配置するサイズ

セクション記述中にアライン指定「. = ALIGN(X)」を入れた場合，アライン指
定により確保されたメモリ領域も，LMA側に配置される．

そのため，データセクションの初期値をROMに配置する場合，セクション記述中
にアライン指定（特に，大きい単位のアライン指定）を入れない方がよい．

○位置カウンタ（'.'）の振舞い

位置カウンタは，セクション記述中では，セクションの先頭からのオフセット
を示す．セクション記述の外側（SECTIONSコマンドの内側）では，最後に配置
したセクションの終了番地の次の番地を指す（初期値は0）．

また，変数としてはアクセスできないが，内部的に，メモリリージョン毎の配
置位置を保持している（と思われる）．配置先メモリリージョンを指定してセ
クションを配置した場合には，位置カウンタではなく，メモリリージョン毎の
配置位置から配置される．

●アライン指定の方法

このことから，アライン指定において，以下の注意が必要である．

具体例として，

	.section1 : {
		<セクション出力記述>
	} > RAM
	. = ALIGN(4K)
	.section2 : {
		<セクション出力記述>
	} > RAM

と記述した場合，.section2は位置カウンタ（'.'）が指す番地から配置される
わけではないため，.section2の先頭番地は4KB境界にアラインされない．

この場合に.section2の先頭番地を4KB境界にアラインさせるためには，(1)
ALIGN指定を.section1のセクション記述中に入れる，(2) アライン用のセクショ
ンを設ける，(3) .section2の配置番地を明示的に指定する，の3つの方法が考
えられる．

(1)の方法は，初期値をROMに配置するセクションの場合，ALIGN指定により確保
されたメモリ領域もROM側に確保されてしまうという問題がある．(2)の方法は，
アライン用のダミーセクションができるため綺麗ではない．(3)の方法は，同じ
メモリリージョンに配置するセクションが連続している場合にしか使用できな
いという制限がある（位置カウンタは，最後に配置したセクションのメモリリー
ジョン中の終了番地の次の番地を指すため）．メモリリージョン毎の配置位置
を保持している変数にアクセスできるとすっきりするが，アクセスする方法は
見つからない．

(3)の方法は次のようになる．ここで，「.section2」の後の「.」は
「ALIGN(4)」としてもよい．

	.section1 : {
		<セクション出力記述>
	} > RAM
	. = ALIGN(4K)
	.section2 . : {
		<セクション出力記述>
	} > RAM

(2)の方法は次のようになる．セクションの中が空の場合には何も処理しない
ため，__dummyラベルを定義してそれを防いでいる．また，「.dummy」の後の
「.」は「ALIGN(4)」としてもよい．

	.section1 : {
		<セクション出力記述>
	} > RAM
	. = ALIGN(4K)
	.dummy . : {
		__dummy = .;
	} > RAM
	.section2 : {
		<セクション出力記述>
	} > RAM

以上より，HRP2カーネルの実装では，LNK_SECの配置を最後にまとめて出力する
ことから，(2)の方法を採用している．LNK_SECの配置方法を変更して，(3)を採
用することも可能であろう（かなり大きい改造になる）．

以上
