TQ2440 学习笔记—— 29、移植U-Boot【U-Boot 的编译、链接过程】

(韦东山——嵌入式Linux 应用开发完全手册)

U-Boot 的编译、链接过程

配置完后,执行” make all“即可编译,从Makefile 中可以了解 U-Boot 使用了哪些文件、哪个文件首先执行、可执行文件占用的内存情况。

先确定用到哪些文件,下面所示为Makefile 中与ARM 相关的部分。


第117、164 行用于包含其他的config.mk 文件,第117行所要包含文件的就是上面的配置过程中制作出来的 include/config.mk文件, 其中定义了 ARCH、CPU、BOARD、SOC等4个变量的值为arm、arm920t、EmbedSky、s3c24x0。

第164行包含顶层目录的config.mk 文件,它们根据上面4个变量的值确定了编译器、编译选项等。其中对我们理解编译过程有帮助的是BOARDDIR、LDFLAGS 的值,如下图所示:


board / EmbedSky/ config.mk中,定义了 “TEXT_BASE = 0x33D00000”。所以结果如下:BOARDDIR 为EmbedSky; LADFLAGS 中有 “-T board /EmbedSky/u-boot.lds -Ttext 0x33D00000”。

TQ2440 学习笔记—— 29、移植U-Boot【U-Boot 的编译、链接过程】_第1张图片

从第169 行可以得知,OBJS 的第一个值为“cpu/$(CPU)/start.o”,即“cpu/arm920T/start.o”。

第193~210 行指定了LIBS 变量就是平台/开发板相关的各个目录、通用目录下相应的库。

OBJS、LIBS所代表的.o、.a 文件就是u-boot 的构成,它们通过如下命令由相应的源文件(或相应子目录下的文件)编译得到。

TQ2440 学习笔记—— 29、移植U-Boot【U-Boot 的编译、链接过程】_第2张图片

第266~268行的规则表示,对于OBJS 中的每个成员,都将进入cpu/$(CPU) 目录(即cpu/arm920t)编译它们。现在OBJS 为cpu/arm/920t/start.o,它将有cpu/arm920t/start.S 编译得到。

第270、271两行的规则表示,对于LIBS中的每个成员,都将进入相应的子目录执行"make"命令。这些子目录中的Makefile,结构相似,它们将Makefile 中指定的文件编译、链接成一个库文件。

当所有的OBJS、LIBS所表示的.o和.a 文件都生成后,就剩最后的链接了,这对应Makefile 中如下几行:


先使用260~264 的规则链接得到ELF 格式的u-boot,最后转换为二进制格式u-boot.bin、S-Record格式u-boot.srec。

LDFLAGS 确定了链接方式,其中的“-T board /EmbedSky/u-boot.lds -Ttext  0x33D00000” 字样指定了程序的布局、地址。

board /EmbedSky/u-boot.lds 文件如下:

TQ2440 学习笔记—— 29、移植U-Boot【U-Boot 的编译、链接过程】_第3张图片

从35行可知,cpu/arm920t/start.o 被放在程序的最前面,所以u-boot 的入口点在cpu/arm920t/start.S 中。


U-Boot 的编译流程总结:

(1)首先编译cpu/$(CPU)/start.S”,对于不同的CPU,还可能编译cpu/$(CPU)”下其他的文件。

(2)然后,对于平台/开发板相关的每个目录、每个通用目录都使用它们各自的Makefile 生成相应的库。

(3)将1、2步骤生成的.o 、.a 文件按照board / EmbedSky/ config.mk 文件中指定的代码起始地址、board /EmbedSky/u-boot.lds 链接脚本链接。

(4)第3步得到的是ELF格式的u-boot,后面的Makefile 还会将它转换为二进制格式、S-Record 格式。

你可能感兴趣的:(处理器【S3C2440】,嵌入式开发【U-Boot】)