针对一个程序而言,她们内部的结构、构成一般是不可见的,然则不可见并不寓意着其内部是杂乱无章的排布,仅仅是众多的二进制数据拼凑而成。一份源代码生成最后的可执行文件来驱动咱们的设备正常工作,中间必经的两个环节是编译和链接。编译的过程好比是厨师将菜炒好,而链接的过程好比是将菜进行摆盘,而端上桌的饭菜便是我们最后的可执行程序。
链接的详细工作由链接器完成,链接器按照链接脚本的内容,根据需求将中间件组装成最后的可执行文件。链接脚本完成的工作重点包含:
1. 输出是什么
2. 输入是什么
3. 需要那些库以及库所在的位置
4. 内存分布位置
5. 起步代码关联内容
基于ARM的SoC U-Boot链接lds文件,重点包括:
1. 指定第1条执行的指令
2. 描述中间件的链接规则
链接器
源码经编译之后的状态是各样的.o文件,如下图所示:
各样.o文件
而每一个中间.o文件都会包括TEXT、DATA、BSS部分内容:
链接的过程大致如下图所示,将每一个.o文件根据下面的规则,生成一个最后的u-boot文件。
图中的TEXT、DATA、BSS段的含义分别是:
1. TEXT,存放程序代码,亦便是包括编程语言规律部分的内容
2. DATA,存放程序中所运用到的数据
3. BSS,存放程序中所运用到的未初始化的数据
U-Boot的链接脚本
针对ARM架构的SoC而言,她们的链接脚本一般在cpu代码文件夹下,这个亦很容易理解,由于链接器毕竟是和架构强关联的,每种架构第1条执行的指令、能够支持哪种起步设备等等,这些都是事先定义好的。
打开上图所示路径中的链接文件,能够发掘链接文件内的代码量并不是非常多,仅仅200多行,因此认识U-Boot的可执行程序的内部形成并不是什么难事。
u-boot.lds文件仅由一个SECTIONS形成,定义了.o文件各个段的最后组织方式、可执行程序的入口点、可执行程序的格式等。
上面13-1行分别定义了输出文件数据为小端、支持ARM、elf格式;
支持ARM架构;
入口符号为__start,亦便是第1条执行的指令是__start,该符号执行完紧接着转到reset入口。
LDS实战
经过修改初始text段的基址,来查看lds文件怎样决定执行程序内部各段的排布状况。text的基位置在顶层Makefile文件的808行运用,定义在include/configs/xxx.h中。
首要直接修改Makefile中的链接位置,如下所示:
修改完成后,查看u-boot.sym中各个段以及各符号的排布状况之后,咱们发掘修改成功了。
修改include/configs/xxx.h中的CONFIG_SYS_TEXT_ADDR
修改后再次编译,查看u-boot.sym
若期盼U-Boot从区别的起步介质加载系统,能够采用第二种方式实现。
|