了解 ARM Cortex-M0+ 重定位

Dav*_*tag 5 arm relocation

我刚刚开始进行嵌入式 arm 开发,有一段代码真的让我很烦恼:

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

if (pSrc != pDest) 
{
    while (pDest < &_erelocate) 
    {
        *pDest++ = *pSrc++;
    }
}
Run Code Online (Sandbox Code Playgroud)

其中_etext_srelocate是链接描述文件中定义的符号:

. = ALIGN(4);
_etext = .;

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

哪里ram是原点为 的内存段0x20000000。我看到的问题是,这_etext是一个标记.text段结束边界的符号,它是不同内存段的一部分rom。这意味着除非上述内存段 100% 已满,_etext != _srelocate否则将始终为真。这意味着我们正在将内存复制.text到根据链接描述文件未定义任何内容的部分之外。

对我来说,这会导致以下三种情况之一:A)rom.text部分之外存在垃圾,并将其复制到.relocate(以及随后.data)中,或 B).text在设备编程之前的芯片擦除操作之后,超出的内存为空,在这种情况下.relocate为零,或 C)这里发生了一些轻微的魔法,其中.data值放在.textin之后rom,并且必须加载到ram; 在这种情况下,评论应该是s/relocate/data.

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

Ric*_*ton 2

你说得对,这是第三种选择。AT ()告诉链接器将.ramfunc.data部分(两者都是读/写的)放在从_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