GNU 链接器和链接器脚本:链接器未生成正确的 LMA

问题描述 投票:0回答:2

我的链接器脚本中有以下行

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

只有这样链接器才能正确运行。

linker overlay gnu memory-address linker-scripts
2个回答
2
投票

这就是我发现的。也许这可以让某人免于数小时令人沮丧的调试。

我的主要问题是有一段汇编代码需要链接到SRAM空间并从闪存空间加载。因此 VMA 必须是 SRAM 地址,LMA 必须是闪存地址。

过去,我总是成功地对 c 文件中定义的函数/数据完成上述操作。我需要做的就是分配一个节属性并适当地修改链接器脚本。

推论 1:链接器允许标准 TEXT 和 DATA 节使用不同的 LMA,尽管它们可能使用节属性进行不同的命名。

当在汇编文件中尝试相同的操作时,就没有这样的运气了。链接器拒绝承认上面定义的输入节 .JumpTable 实际上是用户定义的 TEXT 节。

解决方案就是这样

  1. 将汇编代码移动到新文件JumpTable.S。

  2. 将输入部分 .JumpTable 重命名为 .text

  3. 修改链接器文件如下

     .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
    

也许有更好的解释/另一个根本原因。但这确实拯救了我的一天。


0
投票

刚刚偶然发现了这个老问题,我在

.data
部分也遇到了非常相似的问题。

在我的例子中,原因是

.data
部分是空的,导致
AT
被忽略,遗憾的是。我猜零大小的部分是不可加载的?真糟糕,它混淆了
objcopy
,生成了太大的二进制文件。

不管怎样,我的解决方案是追加一个字节:

    .data : 
    {
        *(.data)
        . = . + 1; /* Waste one byte */
    } >RAM  AT> FLASH
© www.soinside.com 2019 - 2024. All rights reserved.