2016-12-24 72 views
4

我剛開始使用嵌入式ARM開發,並有一個代碼片段,這真的竊聽我:理解的ARM Cortex-M0 +搬遷

/* Initialize the relocate segment */ 
pSrc = &_etext; 
pDest = &_srelocate; 

if (pSrc != pDest) 
{ 
    while (pDest < &_erelocate) 
    { 
     *pDest++ = *pSrc++; 
    } 
} 

_etext_srelocate在鏈接腳本定義的符號:

. = ALIGN(4); 
_etext = .; 

.relocate : AT (_etext) 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram 

ram是一個記憶片段,其原0x20000000。我看到的問題是,_etext是一個符號,表示.text段的末端邊界,它是不同內存段的一部分。這意味着除非上述內存段已滿100%,否則_etext != _srelocate將始終爲真。這意味着我們複製的內容超出.text部分,根據鏈接器腳本,沒有任何內容定義爲活着。

對我來說,這會導致的三種情況之一,要麼A)有本垃圾rom超出.text部分,它被複制到.relocate(隨後.data),或B)以外.text存儲器是空的在設備編程之前進行芯片擦除操作,在這種情況下,.relocate被歸零,或C)存在一些輕微的手工神奇發生,其中.data值被放置在.textrom之後,並且必須被加載到ram;在這種情況下,評論應該是s/relocate/data

第三種情況似乎是最有可能的,但根據鏈接器腳本,這不可能是真實的。有人可以對此有所瞭解嗎?

+0

你說得對,這是第三個選項。 AT()告訴鏈接器將.ramfunc和.data段(兩者都是讀/寫)放在從_etext開始的對象文件中。 「> ram」告訴鏈接器解析重定位,就好像這些部分放在RAM中一樣。結果是程序啓動時,複製循環將數據從只讀區域移動到讀/寫區域。 –

+0

@RichardPennington真棒,你認爲你可以添加這個答案的形式,可能來自涵蓋AT()'指示的ld手冊的引用? –

回答

1

你說得對,這是第三種選擇。該AT()告訴鏈接器將.RAMFUNC。數據部分(這兩者都是讀/寫)在目標文件中開始_etext。 「> ram」告訴鏈接器解決重定位,就好像這些部分被放置在RAM中一樣,這是通過使用MEMORY命令完成的,如下所述:https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY結果是複製循環將數據從只讀區域移動到讀/在程序啓動時寫入區域。

下面是GNU的LD文件,其中控制LMA(加載地址)中描述的鏈接:https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html