いろんなものはつながっている

組み込みOS自作入門(3)実行ファイルの構造

メモリ構成

いまさらではあるが
RAM・・・プログラムから書き込み可能であるが電源OFFで内容が失われる
ROM・・・プログラムから書き込み不可であるが電源OFFでも内容が失われない

H8/3069Fのメモリ構成は
実行ファイル1

となっている。512KBのフラッシュROMと16KBのRAMを内蔵している。

メモリ上に展開されたプログラム

実行ファイルも機械語のコードが置かれているだけというわけではなく、データ領域などもある。メモリ上に展開されたプログラムは一般的に以下の領域を持つ。

実行ファイル2
テキスト領域・・・CPUが実行する機械語コードがおかれる
データ領域 ・・・初期値を持つ静的変数などがおかれる(実行形式ファイルに値を保存しておく)
BSS領域 ・・・初期値を持たない静的変数などがおかれる

実行プログラムがロードされると上記のような領域がメモリのある位置にそれぞれ配置されることになる。どの位置に配置されるかは実行ファイルに含まれるプログラムヘッダーテーブルに書かれている。

プログラムファイルの構成

プログラムを実行すると、ローダがプログラムをメモリに展開する。ただしローダは上記の領域(セクション)ごとにメモリに展開するわけではない。領域(セクション)とは別のセグメントという単位でデータをメモリに展開する。

この本ではgccを使っていてgccが生成する実行形式ファイルフォーマットはELF形式とよばれるもの。ELF形式の構造は大きくわけて以下のようにELFヘッダ、セグメント情報が書かれているプログラムヘッダテーブル、セクション、セクション情報がかかれているセクションヘッダテーブルになっている。

readelfコマンドなのでELF構造を出力してみるとセクションヘッダテーブルには各セクションのアドレス、プログラムヘッダテーブルには、プログラムのセクションをメモリのどの位置にロードするかという情報が書かれている。

リンカ・スクリプト

プログラムの機械語コード領域(.text)やデータ領域(.data)をメモリ上に展開したときにどのアドレスに割り当てるかはリンカが決める。例えば、下記の例では、

SECTIONS
{
	.= 0x0
	
	.vectors : {
		vector.o(.data)
	}
	
	.text : {
		*(.text)
	}
	....

.vectorというセクションを作成し、vector.oの.dataセクションを.vectorに配置している。

リンカはオブジェクトファイルのセクションをまとめることに加えて各セクションをメモリのどこに配置するか、つまりプログラムヘッダテーブルの情報も定義する。例えば

MEMORY
{
	romall(rx)	: o = 0x000000, l = 0x080000
	vector(r)	: o = 0x000000, l = 0x000100
	rom(rx)		: o = 0x000100, l = 0x07ff00
	...
} 

上記のように領域名と開始アドレス(o=)とサイズ(l=)を定義し、セクションの定義の部分で

SECTIONS
{
	.= 0x0
	
	.vectors : {
		vector.o(.data)
	} > vector
	
	.text : {
		_text_start = .;
		*(.text)
		_etext = = .;
	} > rom 
	....

というように各セクションをどのメモリ領域に配置するかを定義する。また、.textセクションに_text_startや_etextが定義されているがこれは.textセクションの最初と最後のアドレスを定義している。これは.textセクションをまるごとどこかにコピーするとかいった場合に使う。

この本ではROM領域に書かれている静的変数を書き換え可能にするため、.dataセクションや.bbsセクションのアドレスをRAM領域に変更し、ROM領域にある.dataセクションや.bbsセクションをRAM領域にコピーすることを説明している。

ROM領域にあるものをRAM領域へコピーする

ROM領域にあるdataセクションをRAM領域にコピーするためリンカで定義したセクションの開始点と終点のアドレスのシンボルを宣言してそれを利用してコピーする。

static int init(void)
{
	extern int erodata, data_start, edata;	// セクションの開始点、終点アドレスの
											// シンボルを参照する
	memcpy(&data_start, &erodata, (long)&edata - (long)&data_start);	// dataセクションに
																		// rodateセクションをコピーする															
}

実行ファイル3

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

スポンサード リンク

カテゴリー

スポンサード リンク