gnu ld脚本总结

那年仲夏 提交于 2020-02-07 00:49:39

GNU ld脚本总结

格式定义

SECTION [ADDRESS] [(TYPE)] : [AT(LMA)]
{
OUTPUT-SECTION-COMMAND
OUTPUT-SECTION-COMMAND
...
} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP]

功能:将*.O的ELF文件的各种段(输入段)通过脚本重新打包并规定好保存地址和执行地址,这个就是bin文件。
SECTION:表示输出段的名称,{}内的内容为*.O的输入段名
LMA: bin存放的地址,一般指ROM。
VMA: 代码运行的地址,例如,当在ram中运行时。
LMA: bin存放的地址,一般指ROM。
[ADDRESS]:表示运行地址(VMA),如果此处不配置VMA则可通过 [AT>LMA_REGION]配置
[AT(LMA)]:bin存放地址定义
[>REGION]: 表示放入的区范围,若section的空间SIZE超出REGION定义的范围则连接器会报错。此时可以设置[ADDRESS]表示在该区域中的具体开始地址;也可以不设置,使用region设置的范围。
注意:
[ADDRESS] [(TYPE)] : [AT(LMA)] 定义了VMA和LMA的起始地址
[>REGION] [AT>LMA_REGION] 定义了VMA和LMA的范围即:起始和结束地址,如果同时设置了[ADDRESS] [(TYPE)] : [AT(LMA)]则起始地址由[ADDRESS] [(TYPE)] : [AT(LMA)]决定。

举例1

//此程序将处于ROM内的已初始化数据拷贝到该数据应在的位置(VMA地址)//并将为初始化数据置零

SECTIONS
{
	.text 0x1000 : { *(.text) _etext = . ; }
	.mdata 0x2000 : AT ( ADDR (.text) + SIZEOF (.text) )//运行地址未0X2000,ROM保存地址为ADDR (.text) + SIZEOF (.text)
	{
		_data = . ; *(.data); _edata = . ; //括号内容为VMA
	}
	.bss 0x3000 : //bss不用保存在rom中因此和运行地址相同。
	{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}
}

程序如下,
extern char _etext, _data, _edata, _bstart, _bend;
char *src = &_etext;
char *dst = &_data;

/* ROM has data at end of text; copy it. */
while (dst < &_edata) {
*dst++ = *src++;
}

/* Zero bss */
for (dst = &_bstart; dst< &_bend; dst++)
*dst = 0

举例2

例如:输出section区域:可以将输出section放入预先定义的内存区域内
MEMORY { rom : ORIGIN = 0x1000, LENGTH = 0x1000 }
SECTIONS { ROM : { *(.text) } >rom }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!