arm-linux-ld命令
首先,要确定我们的程序用没有用到标准的c库,或者一些系统的库文件,这些一般是在操作系统之上开发要注意的问题,这里并不多说,熟悉在Linux编程的人,基本上都会用ld命令;这里,我们从头开始,直接进行汇编语言的连接。
我们写一个汇编程序,控制GPIO,从而控制外接的LED,代码如下;
.global _start
_start:
代码很简单,就是一个对io口进行设置然后写数据。我们看它是如何编译的,注意我们这里使用的不是arm-linux-gcc而是arm-elf-gcc,二者之间没有什么比较大的区别,arm-linux-gcc可能包含更多的库文件,在命令行的编译上面是没有区别。我们来看是如何编译的:
生成bin文件。
-T选项是ld命令中比较重要的一个选项,可以用它直接指明代码的代码段、数据段,对于复杂的连接,可以专门写一个脚本来告诉编译器如何连接。
arm-elf-ld
第二个概念:section,section可以理解成一块,例如像c里面的一个子函数,就是一个section,链接器ld把object文件中的每个section都作为一个整体,为其分配运行的地址(memory layout),这个过程就是重定位(relocation);最后把所有目标文件合并为一个目标文件。
链接通过一个linker script来控制,这个脚本描述了输入文件的sections到输出文件的映射,以及输出文件的memory layout。
因此,linker总会使用一个linker script,如果不特别指定,则使用默认的script;可以使用‘-T’命令行选项来指定一个linker script。
*映像文件的输入段与输出段
linker把多个输入文件合并为一个输出文件。输出文件和输入文件都是目标文件(object file),输出文件通常被称为可执行文件(executable)。
每个目标文件都有一系列section,输入文件的section称为input section,输出文件的section则称为output section。
一个section可以是loadable的,即输出文件运行时需要将这样的section加载到memory(类似于RO&RW段);也可以是 allocatable的,这样的section没有任何内容,某些时候用0对相应的memory区域进行初始化(类似于ZI段);如果一个 section既非loadable也非allocatable,则它通常包含的是调试信息。
每个loadable或 allocatable的output section都有两个地址,一是VMA(virtual memory address),是该section的运行时域地址;二是LMA(load memory address),是该section的加载时域地址。
可以通过objdump工具附加-h选项来查看目标文件中的sections。
*简单的Linker script
(1) SECTIONS命令:
The SECTIONS command tells the linker how to map input sections into output sections, and how to place the output sections in memory.
命令格式如下:
SECTIONS
{
sections-command
sections-command
......
}
其中sections-command可以是ENTRY命令,符号赋值,输出段描述,也可以是overlay描述。
(2) 地址计数器‘.’(location counter):
该符号只能用于SECTIONS命令内部,初始值为‘0’,可以对该符号进行赋值,也可以使用该符号进行计算或赋值给其他符号。它会自动根据SECTIONS命令内部所描述的输出段的大小来计算当前的地址。
(3) 输出段描述(output section description):
前面提到在SECTIONS命令中可以作输出段描述,描述的格式如下:
section [address] [(type)] : [AT(lma)]
{
output-sec
arminuxld命 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)