GNU链接器(LD):存储命令(MEMORY)用法及实例解析
0 参考资料
GNU-LD-v2.30-中文手册.pdf
GNU linker.pdf
1 前言
一个完整的编译工具链应该包含以下4个部分:
(1)编译器
(2)汇编器
(3)链接器
(4)lib库
在GNU工具链中,对应的是:
(1)编译器:GCC(GNU Compiler Collection,GNU编译器套件)
(2)汇编器:GAS(GNU Assembler,GNU汇编器)
(3)链接器:LD(GNU Linker,GNU链接器)
(4)lib库:glibc(GNU C Library,GNU C 库)
本文介绍GNU链接器(LD)链接器脚本中存储命令(MEMORY)用法及实例解析。
2 GNU链接器(LD):存储命令(MEMORY)用法及实例解析
2.1 存储命令(MEMORY)用法
MEMORY命令可以定义存储的大小及首地址,我们可以用它来描述有哪些存储区域可以供链接器使用。链接器会基于存储区域为输出分区设置地址,如果存储区域溢出,链接器也不会打乱分区顺序或裁剪分区。
链接器脚本可能包含多个MEMORY命令,但在不同MEMORY命令定义的存储区域和在同一个MEMORY命令定义的效果是一样的。MEMORY语法如下:
MEMORY
{name [(attr)] : ORIGIN = origin, LENGTH = len…
}
说明:
(1)name是链接器用来引用这个存储区域的名称。每个存储区域都要在 MEMOEY 命令中有唯一的名称。
(2)attr用来指定存储区域的属性,支持属性列表如下(可以使用组合属性,如rwx表示可读可写可执行存储区域):
R-只读分区
W-可读可写分区
X-可执行分区
A-可分配分区
I-初始化的分区
L-可初始化的分区
!-如果未指定存储区域的输出分区匹配任何已经定义的存储区域属性而非!,则会被放置到对应的存储区域内。如果输出分区不匹配存储区域已有属性的则会被纳入该存储区域。
(3)ORIGIN表示存储区域的首地址,必须是数字常量。ORIGIN也可写为org或o
(4)len表示存储区域的大小(单位字节),必须是数字常量。len也可写为len或 l
2.2 存储命令(MEMORY)实例解析
MEMORY
{rom (rx) : ORIGIN = 0, LENGTH = 256Kram (!rx) : org = 0x40000000, l = 4M
}
说明:
上面的例子定义了2个存储区域:
(1)rom,可读可执行,以地址0开始大小为256KB。
(2)ram,!可读可执行,以地址0x40000000,大小4MB。
链接器可以将每个没有指定存储区域的可读或可执行的分区放到rom中;链接器可以将没指定存储区域可读或可执行属性的其它分区放进ram存储区域。
在我们定义好了存储区域后,可以使用>region设置输出分区属性指定输出分区的存储区域。例子如下: