這個東西不是很好說明, 原理大概是這樣:
只討論 c 語言放在 .data section 中的變數。
int i=5;
void f1()
{
}
i 會放在 .data section, 假如在執行檔中的位址是 0x100,
但是你放在 flash 中的 0x100 的話, i 就變成唯讀的, 當你用
i=10 的時候, 是無法寫入的。
該怎麼辦?
放到可以讀寫的記憶體位置, 假設是 0xa100 好了。
那我怎麼作到 a 是 0x100 又是 0xa100 呢?
在 c 語言編譯的時候, 必須讓 i = 10 改成 (*)0xa100 = 10;
而放在 flash 時, i 要是 0x100。
linker script 就是在做這件事情。
再來就是程式在開始執行之前, 需要把 0x100 的 i 複製到 0xa100 上。
很抱歉說得很模糊, 有程式碼來配合會比較容易理解。
https://github.com/descent/stm32f4_prog/blob/master/led/stm32.ld
.data : AT (_etext)
{
_data = .;
*(.data .data.*)
_edata = .;
} > SRAM
https://github.com/descent/stm32f4_prog/blob/master/led/stm32.h
ref: ResetISR
不過不好意思, 沒有更簡化的程式來幫助你理解, 因為要能正確運作 C,
需要的不只是這段。
而麻煩的事情在於怎麼完成這段程式碼, 各個平台有所不同, 這是
cortex m stm32 系列的作法。
而我的作法是 gnu toolchain 的作法, 如果你用不同的開發工具, 細節可能不同,
但基本原理都是一樣的。
※ 引述《wei115 (ㄎㄎ)》之銘言:
: 在沒有作業系統的裝置上(我用的是STM32F104)
: 假使我的程式指令放在只讀的ROM上
: 那我在執行時,要怎麼
: 把可讀可寫的變數和堆疊丟到RAM上?
: 看了一些資料,好像寫連結腳本可以解決?
: 但想想不是阿,連結腳本只是指定哪些資料要放在ROM上,哪些資料要放在RAM上
: 他沒有實際把資料作搬移的工作
: 開機時會要把函式丟到記憶體上並設定堆疊暫存器(以便函式呼叫)
: 並且要把可讀可寫的區段搬移到記憶體上
: 所以編譯器有加入實際搬移的code?讓我在我的程式執行前做好這些工作?
: 有沒有相關資料或關鍵字可供參考,謝謝