我刚刚开始进行嵌入式 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.
第三种情况似乎最有可能,但根据链接描述文件,这不可能是真的。有人可以对此有所了解吗?
你说得对,这是第三种选择。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
| 归档时间: |
|
| 查看次数: |
557 次 |
| 最近记录: |