rtenv是成功大學資訊工程系同學寫出來給CM3的小型作業系統,之前使用rtenv寫作業的時候曾經trace變數trace到C code裏面沒有,但是卻在linker script找到。可是那時候看的感覺就是一堆符號,所以就沒繼續追下去。這也是我想要了解linker script的起點。看完liner script語法後,自然要回來看一下是否可以了解他的描述,先看完整語法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
很長令人害怕嗎?先從大方向拆解
- 程式起始點是
main - 使用
MEMORY指令設了兩個region,分別為FLASH和RAM - 輸出object檔案有三個section,分別是
.text,.data,.bss
然後我們再往下看MEMORY和SETCIONS命令的描述:
MEMORY
1 2 3 4 5 | |
可以看到我們有兩個region
FLASH- 唯讀、可執行
- 起始位址0x00000000
- 長度128k
RAM- 可讀寫和執行
- 起始位址0x20000000
- 長度20k
口說無憑,可以看一下CM3的Memory map,確認一下0x00000000是不是寫程式的區段,而0x20000000是不是RAM的區段(好吧是SRAM)
SECTION
剛才講過有三個section,我們一個一個分別討論:
.text
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
- 這個section要放在FLASH的region
- 所有輸入object檔案的8個section會放入這個輸出object檔案section,分別為
.isr_vector,這個section不可以被garbage collect回收.text- 所有.text.開頭的section
.rodata- 所有.rodata開頭的section
.module.program- 所有.rom.開頭的section
- 這個section有7個symbol,分別是
_smodule.module起始位址
_emodule* `.module`結束位址_sprogram* `.program`起始位址_eprogram* `.program`結束位址_sromdev- 所有.rom.開頭的section集合的起始位址
_eromdev* 所有.rom.開頭的section集合的結束位址_sidata* `.data` section起始位址
這些symbol是有意義的,你需要查詢程式原始碼看他們在做三小。相信我,這值得一看。
.data
1 2 3 4 5 6 7 8 | |
這部份表示
.data的LMA (載入記憶體位址)是_sidata,就是.text結束的地方。另外這邊你要自己搬,有興趣請查原始碼。.data要放在RAM的region- 所有輸入object檔案的2個section會放入這個輸出object檔案section,分別為
.data- 所有.data開頭的section
- 這個section有2個symbol,分別是
_sdata.data的起始位址
_edata.data的結束位址
這些symbol是有意義的,你需要查詢程式原始碼看他們在做三小。相信我,這值得一看。
.bss
1 2 3 4 5 | |
- 所有輸入object檔案的
.bss會放入這個輸出object檔案section .bss要放在RAM的region- 這個section有2個symbol,分別是
_sbss.bss的起始位址
_ebss.bss的結束位址
這些symbol是有意義的,你需要查詢程式原始碼看他們在做三小。相信我,這值得一看。
stack
1
| |
有印象程式使用的stack是由記憶體最後面往前面長的嘛?沒印象?那就估狗linux, stack, text的圖片就可以看到了。這邊也是同樣的概念,所以他的_estack symbol位址會是RAM的開頭位址加上RAM的size。
這些symbol是有意義的,你需要查詢程式原始碼看他們在做三小。相信我,這值得一看。