【问题标题】:How to write this ld script ?如何编写这个 ld 脚本?
【发布时间】:2013-05-12 15:32:05
【问题描述】:

如果我想链接除 z.o 之外的所有 .o 文件。所有 .o(没有 z.o)都重新定位在 0xC0000000,而 z.o 位于 0xFFFF0000,但 z.o 位于文件偏移量 0x8000。

那么,如何编写这个 ld 脚本?

这是我的 loader.lds

SECTIONS { 
    loader      0x00000000 : { start.o loader.o }
    kloader     0x30100000 : AT(4096) { loaderk.o ../lib/klib.a }
    vect        0xFFFF0000 : AT(0x4000) { high_vect.o }
} 

这样好吗???

【问题讨论】:

    标签: arm ld


    【解决方案1】:

    如果你使用input sections 会容易得多。仅使用文件名不是执行此操作的正常方法。问题是在某些时候源模块会相互作用,您将在同一模块中使用来自多个位置的代码和/或数据。因此,制作 loaderkloadervect 部分并使用 gcc attributespragmas 放置代码/数据分段。

    Gnu ld's Input section example 已回答您的问题。输出节列表不必按内存顺序排列。将通配符{ *.o(.text*) }放在最后,不匹配的输入对象将被放置在此部分中。

    一个示例注释函数可能看起来像,

     void data_abort(unsigned int fsr, void* fault) __attribute__ ((section ("vector)))
    

    通常不同部分中的函数/数据必须协作,因此能够将它们混合在同一个源文件中允许编译器对 static 项目执行优化,并将功能相似的项目组合在一起,即使它们可能驻留在在不同的部分。

    我认为这通常会按照您的要求进行。

     SECTIONS { 
         loader      0x00000000 : { start.o loader.o }
         kloader     0x30100000 : AT(4096) { loaderk.o ../lib/klib.a }
         vect        0xFFFF0000 : AT(0x4000) { high_vect.o }
         vect2       0xFFFF0000 : AT(0x8000) { z.o } /* overlay? */
         text        0xC0000000 : { *.o }
     } 
    

    我不确定您是否打算覆盖矢量。您可以使用一些数据表覆盖init 代码。通常你至少要分开.text.data.bss

    始终生成地图文件并仔细检查那里的地址。这比加载和检测代码以确定某些东西被放置在错误的地址要快得多。

    请参阅:Running code from RAMGnu Linker giving unexpected address,以及此问题的相关链接。

    【讨论】:

    • Module 这里的意思是一个源翻译单元。人们常说程序 module 表示“C”文件。该示例可能无法按原样工作。对于overlays,我只是作弊并在链接器文件中定义符号。例如,sections { .mmu_table = .; .init : { *(.init) } }。 Bss 清除、io-muxing 等可以在 .init 部分中,它可以方便地对齐 MMU 表,但您不能重复使用 reset 代码。请参阅Overlay description 了解真正的 方法。
    • 哦,对不起! z.o 是 high_vect.o ,所以没有覆盖 ...... 是不是表示如果之前使用了 z.o 文件,就不会再包含在 *.o 中了?我的 ld 脚本现在好了!!! .Thanks ^_^ ..(看来我需要阅读ld手册)^_^
    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 2011-06-14
    • 2011-11-17
    • 1970-01-01
    • 2020-07-22
    • 2011-06-24
    相关资源
    最近更新 更多