もくもく3rdステップ
- 作者: 坂井弘亮
- 出版社/メーカー: カットシステム
- 発売日: 2010/05
- メディア: 単行本
- 購入: 24人 クリック: 252回
- この商品を含むブログ (39件) を見る
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をゼロクリア。