もくもく3rdステップ

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

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

この本の読書メモ。

H8/3069Fでは0x000000 - 0x07ffffが内蔵ROM(512KB)、0xffbf20 - 0xffff1fが内蔵RAM(16KB)、0xffff20 - 0xffffe9が内蔵I/Oレジスタに割り当てられている。


さっきまでの最小限なリンカスクリプトだとデータ領域やBSS領域が内蔵ROMの所に置かれちゃってるので、書き込めない。困る。
かと言って単にRAM上のアドレスに配置するようにリンクすると今度は初期値が取り出せないのでそれも困る。
なので、リンクするときはRAM上に置き、ロードはROM上に行うような配置にする。

ld.scr
MEMORY
{
	romall(rx)	: o = 0x000000, l = 0x080000 /* 512KB */
	vectors(r)	: o = 0x000000, l = 0x000100 /* top of ROM */
	rom(rx)		: o = 0x000100, l = 0x07ff00

	ramall(rwx)	: o = 0xffbf20, l = 0x004000 /* 16KB */
	data(rwx)	: o = 0xfffc20, l = 0x000300
	stack(rw)	: o = 0xffff00, l = 0x000000 /* end of RAM */
}

メモリマップの定義

SECTIONS
{
	.vectors : {
		vector.o(.data)
	} > vectors

.vectorsはvectorsへ

	.text : {
		_text_start = . ;
		*(.text)
		_etext = . ;
	} > rom

.textはromへ
_text_startを.textの先端に
_etextを.textの終端に

	.rodata : {
		_rodata_start = . ;
		*(.strings)
		*(.rodata)
		*(.rodata.*)
		_erodata = . ;
	} > rom

.rodataはromへ
_rodata_startを.rodataの先端に
_erodataを.rodataの終端に

	.data : {
		_data_start = . ;
		*(.data)
		_edata = . ;
	} > data AT> rom

.dataはdataにおいた状態でリンク、romにおいた状態でロード
_data_startを.dataの先端に(data領域を指す)
_edataを.dataの終端に(data領域を指す)

	.bss : {
		_bss_start = . ;
		*(.bss)
		*(COMMON)
		_ebss = . ;
	} > data AT> rom

.bssはdataにおいた状態でリンク、romにおいた状態でロード
_ebssを.bssの終端に(data領域を指す)

	. = ALIGN(4);
	_end = . ;

	.stack : {
		_stack = .;
	} > stack
}

_stackをRAMの終端に

startup.s
_start:
	mov.l	#_stack,sp

_stackをスタックポインタに入れるよ

main.c
int main(void)
{
  init();

init()を最初に呼ぶよ

static int init(void)
{
  extern int erodata, data_start, edata, bss_start, ebss;

  memcpy(&data_start, &erodata, (long)&edata - (long)&data_start);

.rodataの終端から.data領域のサイズ分_data_startから始まるアドレスへコピー。
これで、ROM上の.data領域をRAM上の.data領域へコピーしてる

  memset(&bss_start, 0, (long)&ebss - (long)&bss_start);

BSSをゼロクリア。