链接脚本为什么会有多个部分命令?

时间:2019-04-11 17:45:58

标签: embedded ld

我一直在阅读sections documentation for ld,但不清楚。

给出部分链接脚本:

MEMORY
{
  FLASH1 (rx) : ORIGIN = 0x000FB000, LENGTH = 0x05000
  FLASH2 (r) : ORIGIN = 0x000FA000, LENGTH = 0x01000
}

SECTIONS
{
  .some_code :
  {
    KEEP(*(SORT(.some_code*)))
  } > FLASH1
}
SECTIONS
{
  .my_page :
  {
    KEEP(*(SORT(.my_page*)))
  } > FLASH2
}

是否有理由在单个链接程序脚本中包含两个以上的分区命令,而不是在一个链接器脚本中具有以下两个全部命令?

SECTIONS
{
  .some_code :
  {
    KEEP(*(SORT(.some_code*)))
  } > FLASH1
  .my_page :
  {
    KEEP(*(SORT(.my_page*)))
  } > FLASH2
}

或者它们是等效的。还有其他情况需要将其拆分吗?

其他说明:我想问一个理由,要有单独的“ SECTIONS”命令(每个命令都有自己的节定义块),而不是在问为什么一般要有分开的节。

1 个答案:

答案 0 :(得分:2)

几乎没有不可避免的需要编写多个SECTIONS命令, 或MEMORY命令(在链接描述文件中)。

SECTIONS
{
    /* Commands... */
}
SECTIONS
{
    /* More commands... */
}

等效于:

SECTIONS
{
    /* Commands... */
    /* More commands... */
}

,对于MEMORY同样如此。

但是,平凡的链接描述文件的可维护性是 如果链接描述文件可以包含多个SECTIONSMEMORY,则将为您提供帮助 命令。例如。如果:

foobar.lds(1)

MEMORY
{
    FOOMEM (rx) : ORIGIN = 0x000FB000, LENGTH = 0x05000
    BARMEM (r) : ORIGIN = 0x000FA000, LENGTH = 0x01000
}

SECTIONS
{
    .foo : {
        *(.foo)
    } > FOOMEM
    .bar : {
        *(.bar)
    } > BARMEM
}

有些琐碎的事情,它可能会更好地重构为:

foobar.lds(2)

INCLUDE ./foo.lds
INCLUDE ./bar.lds

foo.lds

MEMORY
{
    FOOMEM (rx) : ORIGIN = 0x000FB000, LENGTH = 0x05000
}

SECTIONS
{
    .foo : {
        *(.foo)
    } > FOOMEM
}

bar.lds

MEMORY
{
    BARMEM (r) : ORIGIN = 0x000FA000, LENGTH = 0x01000
}

SECTIONS
{
    .bar : {
        *(.bar)
    } > BARMEM
}

以使foobar.lds (2)被链接器扩展为

foobar.lds(3)

MEMORY
{
    FOOMEM (rx) : ORIGIN = 0x000FB000, LENGTH = 0x05000
}

SECTIONS
{
    .foo : {
        *(.foo)
    } > FOOMEM
}

MEMORY
{
    BARMEM (r) : ORIGIN = 0x000FA000, LENGTH = 0x01000
}

SECTIONS
{
    .bar : {
        *(.bar)
    } > BARMEM
}

历史记录:在this obselete GNU ld manual from bygone days中, 我们可以找到约束条件:

  

您可以在一个脚本文件中最多使用一个SECTIONS命令,但是您可以根据需要在其中包含许多语句。

和:

  

一个命令文件最多可以包含MEMORY命令的一种用法;但是,您可以根据需要在其中定义任意数量的内存块。

the current manual中没有的