没有合适的资源?快使用搜索试试~ 我知道了~
首页ARM gcc linker文件编写实例
资源详情
资源评论
资源推荐

Team MCUZONE www.mcuzone.com
www.mcuzone.com - 1 - 20060518
ARM GCC linker 脚本介绍
Team MCUZONE
整理自网络文章
在输入文件在进行链接的时,每个链接都由链接脚本控制着,脚本由链接器命令语言组
成。脚本的主要目的是描述如何把输入文件中的节(sections)映射到输出文件中,并控制
输出文件的存储布局。大多数的链接脚本就是做这些事情的,但在有必要时,脚本也可以指
导链接器执行一些其他的操作。
链接器总是使用链接器脚本,如果你没有提供一个自定义的脚本文件的话,编译器会使用一
个缺省的脚本。
1 链接器脚本的基本概念
链接器把一些输入文件联合在一起,生成输出文件。输出的文件和输入文件都是特定的
object 文件格式,每个文件都可被称为对象文件(object file),而且,输出文件还经常被称为
可执行文件。但这里我们依然称之为对象文件。每个对象文件在其中都包含有一个段
(section)列表,我们有时称输入文件中的段(section)为输入段(input section), 同样,
输出文件中的节称为输出段(output section)。
对象文件中的每一个段都有名字和大小。大多数的段还有一个相连的数据块,就是有名的
"section contents"。一个被标记为可加载(loadable)的 段 ,意味着在输出文件运行时,contents
可以被加载到内存中。没有 contents 的节也可以被加载,实际上除了一个数组被设置外,没
有其他的东西被加载(在一些情况下,存储器必须被清 0)。 而既不是可加载的又不是可分
配的(allocatable)段,通常包含了某些调试信息。
每个可加载或可分配的输出段(output section)都有 2 个地址。第一个是虚拟存储地址 VMA
(virtual memory address),这是在输出文件执行时该段所使用的地址。第二个是加载存储地
址 LMA(load memory address),这是该段被加载时的地址。在大多数情况下,这两个地址
是相同的。举个例子说明不同时的情况:当一个数据节(data section)加载在 ROM 中,后
来在程序开始执行时又拷贝到 RAM 中(在基于 ROM 的系统中,这种技术经常用在初始化
全局变量中)。在这种基于 ROM 的系统情况下,这时,ROM 地址是 LMA,而内存地址是
VMA。
要查看一个对象文件中各个节,可以使用 objdump,并使用"-h"参数。
下图显示了改参数的执行结果,注意段名和地址。
该输出信息可以用来确定每个段的实际尺寸和位置。

Team MCUZONE www.mcuzone.com
www.mcuzone.com - 2 - 20060518
每个对象文件也有一个符号(symbols)列表,这就是著名的符号表(symbols table)。一个符
号可以是"已定义"(defined)或"无定义"(undefined)的。每个符号有名字,并且每个定义
了的符号还有地址。在你编译一个 c/c++程序成对象文件时,每个定义的函数,全局变量,
静态变量,都可以有一个"已定义"的符号。输入文件中引用的每个没有定义的函数和全局变
量则变成"无定义"的符号。
使用 nm 可以查看对象文件中的符号,objdump 并使用"-t"选项也可以。
该信息输出可以用于定位变量和模块的位置。

Team MCUZONE www.mcuzone.com
www.mcuzone.com - 3 - 20060518
2 链接器脚本格式
链接器脚本是一个文本文件。
链接器脚本是一个命令序列,每个命令是一个关键字,可 能 还 带 着 参 数,又或者是对一个符
号的赋值。可以使用分号来隔开命令,而空格则通常被忽略。
像文件名,格式名等字符串通常直接输入,如果文件名包含有像用于分割文件名的逗号等有
其他用处的字符的话,你可以用双引号把文件名括起来。当然没有办法在文件名中使用双引
号了。
可以使用注释,就像 在 C 中,定 界符是"/*"和"*/",和 C 中一样,注释在语法上等同于空格。
3 简单的脚本例子
很多的链接脚本都比较简单。可能最简单的链接器脚本只有一个命令: 'SECTIONS'。使用
'SECTIONS'命令描述输出文件的内存布局。
'SECTIONS'命令功能强大。这里描述一个简单的应用。假设只有代码(code), 初 始 数 据
( initialized data)和未初始化的数据(uninitialized data)。 它 们 要 分 别 被 放 到 '.text', '.data', '.bss'
段中。更进一步假定它们是输入文件中的所有的节。
这个例子中,代码要加载到地址 0x10000,数据要从地址 0x8000000 开始。链接脚本如下:
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
剩余10页未读,继续阅读

















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0