了解 ARM Cortex-M0+ 重定位
Understanding ARM Cortex-M0+ 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
中(并且随后 .data
),或 B) .text
之后的存储器在器件编程之前的芯片擦除操作后为空,在这种情况下 .relocate
被清零,或 C) 有一些轻微的这里发生了魔法,其中 .data
值放在 rom
中的 .text
之后,并且必须加载到 ram
中;在这种情况下,评论应该是 s/relocate/data
.
第三种情况似乎最有可能,但根据链接描述文件,这不可能是真的。有人可以阐明这一点吗?
你没看错,就是第三个选项。 AT() 告诉 linker 将 .ramfunc 和 .data目标文件中的部分(两者都是 read/write),从 _etext 开始。 “> ram”告诉 linker 解析重定位,就像将这些部分放在 RAM 中一样,这是使用此处描述的 MEMORY 命令完成的:https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY 结果是复制循环移动数据从只读区到程序启动时的read/write区
这是 gnu ld 文档的 link,其中描述了控制 LMA(加载地址):https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html
我刚刚开始进行嵌入式 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
中(并且随后 .data
),或 B) .text
之后的存储器在器件编程之前的芯片擦除操作后为空,在这种情况下 .relocate
被清零,或 C) 有一些轻微的这里发生了魔法,其中 .data
值放在 rom
中的 .text
之后,并且必须加载到 ram
中;在这种情况下,评论应该是 s/relocate/data
.
第三种情况似乎最有可能,但根据链接描述文件,这不可能是真的。有人可以阐明这一点吗?
你没看错,就是第三个选项。 AT() 告诉 linker 将 .ramfunc 和 .data目标文件中的部分(两者都是 read/write),从 _etext 开始。 “> ram”告诉 linker 解析重定位,就像将这些部分放在 RAM 中一样,这是使用此处描述的 MEMORY 命令完成的:https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY 结果是复制循环移动数据从只读区到程序启动时的read/write区
这是 gnu ld 文档的 link,其中描述了控制 LMA(加载地址):https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html