如何防止隐式链接器脚本更改节的LMA

问题描述:

我正在使用模块化构建系统的软件,而不是在ARM嵌入式目标上以及正常的X86(linux)计算机上运行。我正在编译GNU工具链,因此使用ld进行链接。如何防止隐式链接器脚本更改节的LMA

其中一个模块利用linkerscript技巧来组装一个“注册”对象数组。

#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在00000000范围内。

问题是,当隐式链接描述文件被添加到命令行ld时,它只会忘记LMA,它会再次等于VMA。我正在拼命寻找一种方法来告诉ld在加载隐式链接描述文件时不要触摸LMA。

+0

只是疯狂的猜测:为ARM构建添加另一个隐式脚本(在已经被使用的脚本之后)会执行:SECTIONS {.data {} AT> ROM}'。或者,如果ARM版本可以首先使用不同的隐式脚本,只需在该脚本的相应位置添加“AT> ROM”即可。 – 2013-02-14 23:16:19

+0

这不起作用,因为ROM内存区域在定义脚本的外部不可用。我已经尝试过了。 – Bart 2013-02-15 06:20:15

+0

你有没有考虑将你的隐式脚本嵌入到ARM的显式脚本中(因此,你会 - 不幸 - 两个脚本 - 一个用于ARM,另一个用于x86的隐式脚本) - 这真的是最简单的解决方案...或者,使用对象的自定义部分? – 2013-02-16 08:28:13

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