通过简单示例学习链接脚本基本语法

  • 格式:pdf
  • 大小:269.79 KB
  • 文档页数:9
2.4.2.4 TYPE TYPE :每个输出section 都有一个类型,如果没有指定TYPE 类型,那么连接 器根据输出section 引用的输入section 的类型设置该输出section 的类型。 它可以为以下五种值, NOLOAD :该section 在程序运行时,不被载入内存。 DSECT,COPY,INFO,OVERLAY :这些类型很少被使用,为了向后兼容才被保 留下来。这种类型的section 必须被标记为“不可加载的”,以便在程序运行不为 它们分配内存。
.text : { *(.text) }>.sram
SECTION [ADDRESS] [(TYPE)] : [AT(LMA)] { OUTPUT-SECTION-COMMAND OUTPUT-SECTION-COMMAND … } [>REGION] [AT>LMA_REGION] [:PHDR HDR ...] [=FILLEXP]
通过简单示例讲解连接脚本基本语法 王兴伟
Linux博客地址: SOC FPGA客户在采用bm模式或简单实时操作系统时,有时会需要修改工程代 码链接的起始地址和地址空间长度。或者在链接脚本中预留栈空间和定义全局变 量等。本文以骏龙公司提供的baremetal 模式代码工程的脚本为例,介绍一下链 接脚本的基本知识,希望起到抛砖引玉的作用。
.text . : { *(.text) } 和 .text : { *(.text) } 这两个描述是截然不同的,第一个将.text section 的VMA 设置为定位符号的 值,而第二个则是设置成定位符号的修调值,满足对齐要求后的。 ADDRESS 可以是一个任意表达式,比如ALIGN(0×10)这将把该section 的 VMA 设置成定位符号的修调值,满足16 字节对齐后的。 注意:设置 ADDRESS 值,将更改定位符号的值。 另外,可以直接修改的值,如 . = 0×10000;
. = ALIGN(4); .data : { *(.data*) }>.sram . = ALIGN(4); .bss : {
bss_start = .; *(.bss*) . = ALIGN(4); bss_end = .; }>.sram }
2.2 脚本中设置入口符号 ENTRY(SYMBOL) : 将符号 SYMBOL 的值设置成入口地址。
2,链接脚本基本语法介绍 2.1 内存区域定义命令 在默认情形下,连接器可以为section 分配任意位置的存储区域。你也可以用
MEMORY 命令定义存储区域,并通过输出section 描述的> REGION 属性显 示地将该输出section 限定于某块存储区域,当存储区域大小不能满足要求时, 连接器会报告该错误。 MEMORY 命令的文法如下, MEMORY { NAME1 [(ATTR)] : ORIGIN = ORIGIN1, LENGTH = LEN2 NAME2 [(ATTR)] : ORIGIN = ORIGIN2, LENGTH = LEN2 … } NAME :存储区域的名字,这个名字可以与符号名、文件名、section 名重复, 因为它处于一个独立的名字空间。 ATTR :定义该存储区域的属性,ATTR 属性内可以出现以下7 个字符, R 只读section W 读/写section X 可执行section A „可分配的‟section I 初始化了的 section L 同I ! 不满足该字符之后的任何一个属性的section
start.o (.text) *(.text*) } >.sram . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } >.sram . = ALIGN(4); .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram . = ALIGN(4); .bss : { . = ALIGN(4); __bss_start = .; *(.bss*) . = ALIGN(4); __bss_end__ = .; } >.sram }
2.4.2.4 LMA,指示存放在ROM中代码或数据的地址(如果VMA和LMA不同的 话),使用时需要根据该地址加载到ram中 输出section 的LMA :默认情况下,LMA 等于VMA,但可以通过关键字AT() 指定 LMA。
用关键字AT()指定,括号内包含表达式,表达式的值用于设置LMA。如果不用 AT()关键字,那么可用AT>LMA_REGION 表达式设置指定该section 加载地 址的范围。 这个属性主要用于构件ROM 境象。 例子, SECTIONS { .text 0×1000 : { *(.text) _etext = . ; } //代码在rom中运行 .mdata 0×2000 :
1.2 入口地址 定义了本工程代码运行时的入口函数。在本例中入口函数为“_start”,即汇编
代码start.s中的入口函数。 ENTRY(_start) 需要注意如下备注: 备注1,链接过程中,需要首先链接start.o文件,以保证_start 函数位于程序 地址空间的最前端。后面会有说明。 备注2,_start 函数需要位于start.s最前端。_start通常是上电复位函数。如 下图所示
2.4.1 SECTION-COMMAND 有四种: (1) ENTRY 命令 (2) 符号赋值语句 (3) 一个输出section 的描述(output section description) (4) 一个 section 叠加描述(overlay description)
ቤተ መጻሕፍቲ ባይዱ2.4.2 输出section 描述
例子 2 MEMORY { .sram : ORIGIN = 0x00200000, LENGTH = (32 * 1024 * 1024) } OUTPUT_ARCH(arm) ENTRY(start)
SECTIONS {
.text : {
BSP/start.o (.text) *(.text) }>.sram . = ALIGN(4); .rodata : { *(.rodata*) }>.sram
会将 SYMBOL 处指令连接到下面的 ORIGIN 指定的地址。 MEMORY { .sram : ORIGIN = 0x01000000, LENGTH = (16 * 1024 * 1024) }
ld 有多种方法设置进程入口地址, 按一下顺序: (编号越前, 优先级越高) 1, ld 命令行的-e 选项 2, 连接脚本的ENTRY(SYMBOL)命令 3, 如果定义了start 符号, 使用start 符号值 4, 如果存在.text section, 使用.text section 的第一字节的位置值 5, 使用值 0
2.4.2.1 SECTION: section 名字 SECTION 左右的空白、圆括号、冒号是必须的,换行符和其他空格是可选的。 2.4.2.2 OUTPUT-SECTION-COMMAND 每个OUTPUT-SECTION-COMMAND 为以下四种之一, 符号赋值语句
一个输入section 描述 //可以看到,输入section描述是输出的一部分 直接包含的数据值 一个特殊的输出section 关键字 2.4.2.3 ADDRESS 输出section 地址(ADDRESS): ADDRESS是一个表达式,它的值用于设置VMA。如果没有该选项且有REGION 选项,那么连接器将根据REGION 设置VMA;如果也没有 REGION 选项,那 么连接器将根据定位符号„.‟的值设置该section 的VMA,将定位符号的值调整 到满足输出section 对齐要求后的值,输出 section 的对齐要求为:该输出 section 描述内用到的所有输入section 的对齐要求中最严格的。
1,初识链接脚本 下面的就是骏龙公司提供的baremetal工程的链接脚本。 MEMORY { .sram : ORIGIN = 0x01000000, LENGTH = (16 * 1024 * 1024) } OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { .text : {
2.3 定位器符号的使用 在脚本中经常看到类似“. = 0×10000;”的语句,该语句表示将当前地址设置 为0x10000。在链接开始处没有定位器符号,则表示将输入段定位到MEMORY 定义的空间最开始处,即offset为0。
以下脚本将输出文件的text section 定位在0×10000, data section 定位在 0×8000000: SECTIONS { . = 0×10000; .text : { *(.text) } . = 0×8000000; .data : { *(.data) } .bss : {
ORIGIN :关键字,区域的开始地址,可简写成org 或o LENGTH :关键字,区域的大小,可简写成 len 或 l
例子1, MEMORY { rom (rx) : ORIGIN = 0, LENGTH = 256K ram (!rx) : org = 0×40000000, l = 4M }
. = ALIGN(4);
__bss_start = .; *(.bss*) . = ALIGN(4); __bss_end__ = .; } >.sram}
2.4. SECTIONS 命令 SECTIONS 命令告诉ld 如何把输入文件的sections 映射到输出文件的各个 section: 如何将输入section 合为输出section; 如何把输出section 放入程 序地址空间 SECTIONS { SECTIONS-COMMAND SECTIONS-COMMAND … }