了解ARM Cortex-M0 +重定位

时间:2016-12-24 14:24:31

标签: arm relocation

我刚刚开始使用嵌入式arm开发,并且有一段代码真的让我烦恼:

/* 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段的结束边界的符号,它是不同内存段rom的一部分。这意味着除非上述内存段100%已满,_etext != _srelocate将始终为真。这意味着我们将内存复制到.text部分之外,根据链接描述文件没有定义任何内容。

对我而言,这导致三种情况之一,A)rom部分之外的.text中存在垃圾,并将其复制到.relocate(以及随后{ {1}})或B)在器件编程之前的芯片擦除操作之后,超出.data的存储器为空,在这种情况下.text被置零,或者C)有一些轻微的手部魔法发生在.relocate .data .text之后的rom值,并且必须加载到ram;在这种情况下,评论应为s/relocate/data

第三种情况似乎最有可能,但根据链接器脚本,这不可能是真的。有人可以对此有所了解吗?

1 个答案:

答案 0 :(得分:1)

你是对的,这是第三种选择。 AT()告诉链接器将 .ramfunc .data 部分(两者都是读/写)放在目标文件中从 _etext 开始。 “&gt; ram”告诉链接器解析重定位,好像这些节放在RAM中这是使用MEMORY命令完成的,如下所述:https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY结果是复制循环从只读中移动数据程序启动时读/写区域的区域。

这是指向控制LMA(加载地址)的gnu ld文档的链接:https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html