GNU LD(Linker Scripts)链接介绍

背景

使用链接脚本可对链接过程进行显式控制,允许对链接器的输入文件和输出文件之间的映射进行完整的规范。一般使用-T选项来显示的指定链接脚本。

  • input files
  • file formats
  • output file layout
  • addresses of sections
  • placement of common blocks

语法

ld脚本是语句的集合,一些是设置特定选项的简单关键字,一些用于选择和分组输入文件、一些用于命名输出文件,其中SECTIONSMEMORY是有对链接过程具有基本和普遍的影响。

SECTIONS

section命令中最常用的语句是section定义,它指定输出部分的属性:它的位置、对齐方式、内容、填充模式和目标内存区域。这些规范中的大多数是可选的。

定义

通过以下几种形式来指定不同的section,filename可以使用*等正则表达式,section可以用逗号或者空格区分。

filename( section )
filename( section , section, ... )
filename( section section ... )

例子

在下面的示例中,命令脚本将输出文件排列成三个连续的部分,分别命名为.text、.data和.bss,并从所有输入文件中相应命名的部分获取每个部分的输入

SECTIONS { 
  .text : { *(.text) }
  .data : { *(.data) } 
  .bss :  { *(.bss)  *(COMMON) } 
}

这个例子展示了如何使用通配符模式对文件进行分区。所有的.text部分放在.text中,所有的.bss部分放在.bss中。对于所有以大写字符开头的文件,.data节被放在.data,对于所有其他文件,.data节被放置在.data中。

SECTIONS {
  .text : { *(.text) }
  .DATA : { [A-Z]*(.data) }
  .data : { *(.data) }
  .bss : { *(.bss) }
}

MEMORY

链接器的默认配置允许分配所有可用内存。可以使用MEMORY命令覆盖此配置。MEMORY命令描述目标器中内存块的位置和大小。通过仔细使用它,您可以描述链接器可能使用哪些内存区域,以及它必须避免哪些内存区域。链接器将请求的分段移动到正确的内存块中,并在内存块太满时发出错误。

一个链接脚本最多只能有一条MEMORY命令,但是可以定义多个内存块。

MEMORY 
  {
    name (attr) : ORIGIN = origin, LENGTH = len
    ...
  }
  • name

是链接器内部用来引用区域的名称。可以使用任何符号名。

  • (attr)

属性的可选列表,指定是否使用特定内存来放置链接器脚本中未列出的部分。有效的属性列表必须由字符“ALIRWX”组成,以匹配部分属性。如果你省略了属性列表,你也可以省略它周围的括号。目前支持的属性有:

`Letter'
	Section Attribute
`R'
	Read-only sections.
`W'
	Read/write sections.
`X'
	Sections containing executable code.
`A'
	Allocated sections.
`I'
	Initialized sections.
`L'
	Same as I.
`!'
	Invert the sense of any of the following attributes.
  • origin

物理内存中区域的起始地址。它是一个表达式,在执行内存分配之前必须求值为一个常量。关键字ORIGIN可以缩写为org或o(但不能,例如“ORG”)。

  • len

以字节为单位的区域大小(表达式)。关键字LENGTH可以缩写为len或l。

  • exmaple

指定内存有两个可供分配的区域:一个从0开始分配256kb字节,另一个从0x40000000开始分配4mb字节。rom内存区域将获得所有没有显式的只读或包含代码的内存section,而ram内存区域将获得数据section。

MEMORY 
  {
  rom (rx)  : ORIGIN = 0, LENGTH = 256K
  ram (!rx) : org = 0x40000000, l = 4M
  }

reference

资料

posted @ 2022-03-25 18:13  zephyr~  阅读(1108)  评论(0编辑  收藏  举报