2016-12-24 34 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