我刚刚开始使用嵌入式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
。
第三种情况似乎最有可能,但根据链接器脚本,这不可能是真的。有人可以对此有所了解吗?
答案 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