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

組み込みOS自作入門(7)ダウンロードしたプログラムの起動

ブートローダからダウンロードしたプログラムを起動する

シリアル経由でダウンロードしたプログラムを起動することを考える。現状、ダウンロードしたプログラムはいったんRAM領域に確保したバッファにコピーされている。この位置はあくまでも一時的なものでプログラムヘッダーに書かれ設定されているプログラム(セグメント)のアドレスとは異なる。したがってバッファにコピーされたプログラムをプログラムヘッダで指定されているアドレスにコピーする必要がある。
プログラム起動1

そのためにまずはバッファにダウンロードしたプログラムのヘッダからプログラムヘッダの位置、プログラムヘッダの数を取得する。プログラムヘッダの内容を参照してバッファ領域から所定のアドレスへセグメントをコピーする。

static int elf_load_program(struct elf_header *header)
{
	struct elf_program_header *phdr;
	int i = 0;
	// セグメントをひとつひとつ定められたアドレスへコピーする
	for(i = 0; i < header->program_header_num; i++){
		
		// プログラムヘッダを取得する
		 *phdr = (struct elf_program_header*)
		 	((char*)header + header->pgoram_header_offset + 
		 	header->program_header_size * i);
	
		// バッファにあるセグメントの位置とサイズを指定して所定のアドレスへコピー
		memcpy((char*)phdr->physical_addr, (char*)header + phdr->offset,
			phdr->file_size);
		// ファイルサイズとメモリサイズに差がある場合は0でうめておく
		memset((char*)phdr->physical_addr + phdr->file_size, 0,
			phdr->memory_size - phdr->file_size);
			
	}
}

原理的にはプログラムヘッダのみをバッファにコピーしてセグメントは直接所定の位置に書き込むことも可能。

ダウンロードされるプログラムのエントリポイントをリンカで設定

ダウンロードされるプログラムをすべてRAM領域に配置されるようにするためリンカで各セクションの配置位置をRAM領域へ変更。

OUTPUT_FORMAT("elf32-h8300")
OUTPUT_ARCH(h8300h)
ENTRY("_start") /*エントリポイントの指定*/

MEMORY
{
	ram(rwx)	: o = 0xffc020, l = 0x003f00
	stack(rw)	: o = 0xffff00, l = 0x000000 /* end of RAM*/
}

SECTIONS
{
	.text : {
	....
	} > ram /*.textセクションをRAMへ*/
	
	....
}

関連記事

コメント

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

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

スポンサード リンク

カテゴリー

スポンサード リンク