【问题标题】:How to prevent implicit linker script changing the LMA of a section如何防止隐式链接描述文件更改部分的 LMA
【发布时间】:2013-01-30 14:16:31
【问题描述】:

我正在使用模块化构建系统来构建软件,而不是在 ARM 嵌入式目标以及普通 X86 (linux) 机器上运行。我正在使用 GNU 工具链进行编译,因此使用 ld 进行链接。

其中一个模块利用链接脚本技巧来组装一组“已注册”对象。对象是使用这样的宏创建的:

#define RegObject(name, arg1, arg2, etc) \
    static TRegObject name \
    __attribute__((section ("regobj_table"), used)) = \
    { arg1, arg2, etc }

该模块还在链接步骤中添加了implicit linker script,如下所示:

SECTIONS
{
    .data : ALIGN(4)
    {
        regobj_table_start = .;
        KEEP(*(regobj_table))
        regobj_table_end = .;
    }
}

代码使用regobj_table_startregobj_table_end 符号来查找已注册的对象。此解决方案适用于本机 (Linux) 编译目标。

但这不适用于 ARM 目标。原因是我有一个用于目标的自定义默认链接器脚本(它是一个微型微控制器,在没有操作系统的情况下运行),它为.data 部分定义了一个加载内存地址。这是因为该部分存储在闪存中,但是一旦微控制器启动,它就会被复制到 RAM。链接描述文件的相关部分如下所示:

MEMORY
{
  ROM (rx)  : ORIGIN = 0x00000000, LENGTH = 512k
  RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 32k
}

SECTIONS
{
    /* ... other stuff ... */

    .data :
    {
        _data = .;
        *(.data)
        *(.data.*)
    } >RAM AT>ROM

    /* ... even more stuff ... */
}

这会将.data 部分的 VMA 设置为 0x4000000 范围内的某个位置,并将 LMA 设置为 0x00000000 范围内的某个位置。

问题是当隐式链接器脚本被添加到ld 的命令行时,它只是忘记了LMA,它又变成了等于VMA。我正在拼命寻找一种方法来告诉ld 在加载隐式链接器脚本时不要触摸LMA。

【问题讨论】:

  • 只是一个疯狂的猜测:为 ARM 构建添加另一个隐式脚本(在已经使用的脚本之后)是否可以解决问题:SECTIONS { .data { } AT >ROM }。或者,如果 ARM 构建可以首先使用不同的隐式脚本,只需在该脚本的适当位置添加 AT>ROM
  • 这不起作用,因为 ROM 内存区域在定义它的脚本之外不可用。我已经试过了。
  • 您是否考虑过将隐式脚本嵌入到 ARM 的显式脚本中(因此,不幸的是,您将拥有两个脚本 - 一个用于 ARM,一个用于 x86 的隐式短脚本)- 这确实是最简单的解决方案......或者也许使用对象的自定义部分?
  • 除了不可能(参考隐式脚本中的 ROM 部分)之外,我确实想让隐式脚本与底层架构“不可知”。现在我正在解决这个问题,方法是使用.rodata 部分(具有相等的 LMA 和 VMA)来保持指向数据部分中已注册对象的指针。

标签: c embedded ld binutils linker-scripts


【解决方案1】:

尝试使用 INSERT AFTER ... 作为最后一行。这会将您的脚本插入到默认脚本中。

【讨论】:

    猜你喜欢
    • 2017-02-04
    • 2018-12-29
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多