我的链接器脚本中有以下行
JumpTable ABSOLUTE(0x2000000C): AT(eROData)
{
JumpTableStart = .;
*(.JumpSection);
. = ALIGN(4);
JumpTableEnd = .;
} > SRAM
eROData 是闪存中的地址,假定值为 0x1000xxxx
链接后,我注意到链接器将 VMA 和 LMA 分配给了 JumpTable 部分。 这是列表文件中的列表。
2 .rodata 00000004 10001214 10001214 00001214 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 JumpTable 00000140 2000000c 2000000c 00008954 2**2
CONTENTS, READONLY
.data 部分没有这样的问题。
这是一个已知的 GNU 链接器问题吗?
编辑: 我注意到,如果在 C 文件中定义了“.JumpSection”部分,则 LMA 被正确分配。
我面临这个问题,因为该部分是在程序集文件中定义的。
您以前遇到过这个问题吗?
编辑 - 解决方案: 事实证明 .JumpSection 必须使用正确的属性进行定义: .section“.JumpSection”,“ax”,%progbits
只有这样链接器才能正确运行。
这就是我发现的。也许这可以让某人免于数小时令人沮丧的调试。
我的主要问题是有一段汇编代码需要链接到SRAM空间并从闪存空间加载。因此 VMA 必须是 SRAM 地址,LMA 必须是闪存地址。
过去,我总是成功地对 c 文件中定义的函数/数据完成上述操作。我需要做的就是分配一个节属性并适当地修改链接器脚本。
推论 1:链接器允许标准 TEXT 和 DATA 节使用不同的 LMA,尽管它们可能使用节属性进行不同的命名。
当在汇编文件中尝试相同的操作时,就没有这样的运气了。链接器拒绝承认上面定义的输入节 .JumpTable 实际上是用户定义的 TEXT 节。
解决方案就是这样
将汇编代码移动到新文件JumpTable.S。
将输入部分 .JumpTable 重命名为 .text
修改链接器文件如下
.text :
{
*(EXCLUDE_FILE(*JumpTable.o) .text); /* Exclude .text of JumpTable.o and place others */
} > FLASH
JumpTable ABSOLUTE(0x2000000C) : AT (eROData) /* Link to SRAM and Load after const data */
{
JumpTableStart = .;
*JumpTable.o(.text); /* Place .text of JumpTable.o into JumpTable output section) */
JumpTableEnd = .;
} > SRAM
也许有更好的解释/另一个根本原因。但这确实拯救了我的一天。
刚刚偶然发现了这个老问题,我在
.data
部分也遇到了非常相似的问题。
在我的例子中,原因是
.data
部分是空的,导致AT
被忽略,遗憾的是。我猜零大小的部分是不可加载的?真糟糕,它混淆了 objcopy
,生成了太大的二进制文件。
不管怎样,我的解决方案是追加一个字节:
.data :
{
*(.data)
. = . + 1; /* Waste one byte */
} >RAM AT> FLASH