1

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

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

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

4

1 回答 1

1

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

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

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

推论 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
    

也许有更好的解释/另一个根本原因。但这肯定挽救了我的一天。

于 2012-12-08T03:35:05.193 回答