/****************************************************************
uboot的链接脚本:u-boot.lds
时间:2018年11月下旬
作者:cryil_先森
*******************************************************************/
***目录:/uboot/board/samsung/smdkc110(board)/u-boot.lds
***职责与作用:
1.将若干输入文件(.o文件)根据一定规则合并为一个输出文件(例如ELF格式的可执行文件
2.将符号与地址绑定(当然加载器也要完成这一部分工作)。链接器有一个编译到其二进制代码中的默认链接脚本,大多数情况下使用它链接输入文件并生成目标文件
注:uboot更需要规则,因为涉及到重定位问题,重定位相关代码必须要放到前16KB之前。(此外,链接脚本还可以自己定义自己的段实现按段排列顺序执行程序,需源码有相关代码支持)
***分析:
1.指定输出格式和入口地址
指定输出的格式,然后指定输出的架构是arm架构的;
指定了整个程序的入口地址:_start;
在裸机程序之中,指定程序的链接地址的方法:
1.Makefile中 ld flag -Ttext 0x20000000
2.在连接脚本中的SECTIONS开头用.=0x00000000来指定。
注:程序的入口不一定就代表它位于储存介质的起始位置,一般的起始位置存放的是16字节的校验头和异常向量表。
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
2.链接地址和地址划分
SECTIONS表示正式开始地址划分;
“.”的意思是当前地址,这句将当前地址(代码段起始地址)设为0x00000000,但是其实这个地址会被config.mk用-Ttext$(TEXT_BASE)指定的虚拟地址0xc3e00000(由顶层Makefile填充给config.mk)覆盖掉
.text表示开始代码段的链接;
代码段的链接顺序很重要,首先start.o必须在第一个;
由于uboot需要重定位,故所有和重定位有关的代码必须链接在最前面,作为16kb的bl1。而其他所有的.o文件就往后任意链接了;
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/s5pc11x/start.o (.text)
cpu/s5pc11x/s5pc110/cpu_init.o (.text)
board/samsung/smdkc110/lowlevel_init.o (.text)
cpu/s5pc11x/onenand_cp.o (.text)
cpu/s5pc11x/nand_cp.o (.text)
cpu/s5pc11x/movi.o (.text)
common/secure_boot.o (.text)
common/ace_sha1.o (.text)
cpu/s5pc11x/pmic.o (.text)
*(.text)
}
注:在代码段注意文件的排列的顺序,指定放在前面的文件是安排在16kb内的文件,这些文件函数在前16kb会被调用,用来初始化ddr,sd之类的。
=ALIGN(4)的意思是将当前地址(代码段结束地址)四字节对齐,然后将其作为只读数据段的起始地址(存放只读的全局变量);
同理,对数据段(存放全局变量)和got段进行相同设置;
而uboot的最终起始地址是在Makefile中用-Ttext指定的,而具体的地址由Makefile中规定的参数TEST_BASE决定,在根目录 执行make xxx.config时得到。