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

上传人:wt****50 文档编号:44633335 上传时间:2018-06-14 格式:PDF 页数:9 大小:269.79KB
返回 下载 相关 举报
通过简单示例学习链接脚本基本语法_第1页
第1页 / 共9页
通过简单示例学习链接脚本基本语法_第2页
第2页 / 共9页
通过简单示例学习链接脚本基本语法_第3页
第3页 / 共9页
通过简单示例学习链接脚本基本语法_第4页
第4页 / 共9页
通过简单示例学习链接脚本基本语法_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《通过简单示例学习链接脚本基本语法》由会员分享,可在线阅读,更多相关《通过简单示例学习链接脚本基本语法(9页珍藏版)》请在金锄头文库上搜索。

1、通过简单示例讲解连接脚本基本语法 王兴伟 Linux博客地址: SOC FPGA客户在采用bm模式或简单实时操作系统时,有时会需要修改工程代 码链接的起始地址和地址空间长度。 或者在链接脚本中预留栈空间和定义全局变 量等。 本文以骏龙公司提供的baremetal 模式代码工程的脚本为例,介绍一下链 接脚本的基本知识,希望起到抛砖引玉的作用。 1,初识链接脚本 下面的就是骏龙公司提供的baremetal工程的链接脚本。 MEMORY .sram : ORIGIN = 0x01000000, LENGTH = (16 * 1024 * 1024) OUTPUT_FORMAT(“elf32-litt

2、learm“, “elf32-littlearm“, “elf32-littlearm“) OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS .text : 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

3、 = .; *(.bss*) . = ALIGN(4); _bss_end_ = .; .sram 在介绍脚本基本语法之前,先介绍一下上面脚本各个部分的功能,以便给大 家一个整体的认识,避免陷入具体的语法细节。 1.1 代码运行空间 在脚本中以MEMORY关键字定义存储空间, 其中以ORIGIN定义地址空间的起始地址, LENGTH定义地址空间的长度。如下下面的语句定义了该工程运行的起始地址为 0x01000000,地址空间的长度为16MB。这部分内容是大家最经常修改的内容。 MEMORY .sram : ORIGIN = 0x01000000, LENGTH = (16 * 1024 * 1

4、024) 1.2 入口地址 定义了本工程代码运行时的入口函数。在本例中入口函数为“_start”,即汇编代码start.s中的入口函数。 ENTRY(_start) 需要注意如下备注: 备注1,链接过程中,需要首先链接start.o文件,以保证_start 函数位于程序 地址空间的最前端。后面会有说明。 备注2,_start 函数需要位于start.s最前端。_start通常是上电复位函数。如 下图所示 1.3 程序段链接 SECTIONS .text : start.o (.text) *(.text*) .sram 在上面的语句的start.o (.text)指示将编译的工程文件中的sta

5、rt.o的.text段 (即代码段)链接到MEMORY定义的sram中。 *(.text*)指示将工程中所有目标文件的.text段链接到sram中。 在链接*(.text*) 时,不会重复链接start.o的.text段。 另外,此处的链接过程是按照顺序进行链接的,即先链接start.o,再链接其他 的目标文件。这样可以保证start.o被链接到运行地址空间的最前端。 2,链接脚本基本语法介绍 2.1 内存区域定义命令 在默认情形下,连接器可以为section 分配任意位置的存储区域。你也可以用 MEMORY 命令定义存储区域,并通过输出section 描述的 REGION 属性显 示地将该输

6、出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

7、 A 可分配的section I 初始化了的 section L 同I ! 不满足该字符之后的任何一个属性的section ORIGIN :关键字,区域的开始地址,可简写成org 或o LENGTH :关键字,区域的大小,可简写成 len 或 l 例子1, MEMORY rom (rx) : ORIGIN = 0, LENGTH = 256K ram (!rx) : org = 040000000, l = 4M 例子 2 MEMORY .sram : ORIGIN = 0x00200000, LENGTH = (32 * 1024 * 1024) OUTPUT_ARCH(arm) ENTRY

8、(start) SECTIONS .text : BSP/start.o (.text) *(.text) .sram . = ALIGN(4); .rodata : *(.rodata*) .sram . = ALIGN(4); .data : *(.data*) .sram . = ALIGN(4); .bss : bss_start = .; *(.bss*) . = ALIGN(4); bss_end = .; .sram 2.2 脚本中设置入口符号 ENTRY(SYMBOL) : 将符号 SYMBOL 的值设置成入口地址。 会将 SYMBOL 处指令连接到下面的 ORIGIN 指定的

9、地址。 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.3 定位器符号的使用 在脚本中经常看到类似“. = 010000;”的语句,该语句表示将当前地址设置 为0x10000。在链接开

10、始处没有定位器符号,则表示将输入段定位到MEMORY 定义的空间最开始处,即offset为0。 以下脚本将输出文件的text section 定位在010000, data section 定位在 08000000: SECTIONS . = 010000; .text : *(.text) . = 08000000; .data : *(.data) .bss : . = ALIGN(4); _bss_start = .; *(.bss*) . = ALIGN(4); _bss_end_ = .; .sram 2.4. SECTIONS 命令 SECTIONS 命令告诉ld 如何把输入文件的

11、sections 映射到输出文件的各个 section: 如何将输入section 合为输出section; 如何把输出section 放入程 序地址空间 SECTIONS SECTIONS-COMMAND SECTIONS-COMMAND 2.4.1 SECTION-COMMAND 有四种: (1) ENTRY 命令 (2) 符号赋值语句 (3) 一个输出section 的描述(output section description) (4) 一个 section 叠加描述(overlay description) 2.4.2 输出section 描述 .text : *(.text) .sr

12、am SECTION ADDRESS (TYPE) : AT(LMA) OUTPUT-SECTION-COMMAND OUTPUT-SECTION-COMMAND REGION ATLMA_REGION :PHDR HDR . =FILLEXP 2.4.2.1 SECTION: section 名字 SECTION 左右的空白、圆括号、冒号是必须的,换行符和其他空格是可选的。 2.4.2.2 OUTPUT-SECTION-COMMAND 每个OUTPUT-SECTION-COMMAND 为以下四种之一, 符号赋值语句 一个输入section 描述 /可以看到,输入可以看到,输入sections

13、ection描述是输出的一部分描述是输出的一部分 直接包含的数据值 一个特殊的输出section 关键字 2.4.2.3 ADDRESS 输出section 地址(ADDRESS): ADDRESS是一个表达式, 它的值用于设置VMA。 如果没有该选项且有REGION 选项,那么连接器将根据REGION 设置VMA;如果也没有 REGION 选项,那 么连接器将根据定位符号.的值设置该section 的VMA,将定位符号的值调整 到满足输出section 对齐要求后的值,输出 section 的对齐要求为:该输出 section 描述内用到的所有输入section 的对齐要求中最严格的。 .t

14、ext . : *(.text) 和 .text : *(.text) 这两个描述是截然不同的,第一个将.text section 的VMA 设置为定位符号的 值,而第二个则是设置成定位符号的修调值,满足对齐要求后的。 ADDRESS 可以是一个任意表达式,比如ALIGN(010)这将把该section 的 VMA 设置成定位符号的修调值,满足16 字节对齐后的。 注意:设置 ADDRESS 值,将更改定位符号的值。 另外,可以直接修改的值,如 . = 010000; 2.4.2.4 TYPE TYPE :每个输出section 都有一个类型,如果没有指定TYPE 类型,那么连接 器根据输出s

15、ection 引用的输入section 的类型设置该输出section 的类型。 它可以为以下五种值, NOLOAD :该section 在程序运行时,不被载入内存。 DSECT,COPY,INFO,OVERLAY :这些类型很少被使用,为了向后兼容才被保 留下来。这种类型的section 必须被标记为“不可加载的”,以便在程序运行不为 它们分配内存。 2.4.2.4 LMA,指示存放在ROM中代码或数据的地址(如果VMA和LMA不同的 话),使用时需要根据该地址加载到ram中 输出section 的LMA :默认情况下,LMA 等于VMA,但可以通过关键字AT() 指定 LMA。 用关键字AT()指定,括号内包含表达式,表达式的值用于设置LMA。如果不用 AT()关键字,那么可用ATLMA_REGION 表达式设置指定该section 加载地 址的范围。 这个属性主要用于构件ROM 境象。 例子, SECTIONS .text 01000 : *(.text) _etext = . ; /代码在代码在rom中运行中运行 .mdata

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号