以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
参考博客:u-boot Makefile完全解读_williamwang2013的博客-CSDN博客
参考博客:U-boot主Makefile分析_XiaoBaWu的博客-CSDN博客
参考博客:U-boot配置及编译阶段流程宏观分析_XiaoBaWu的博客-CSDN博客
uboot来源于官方(uboot官网下载),或者SoC官方(研发s5pv210芯片的公司推出的开发板,SMDKV210),或者具体的开发板的官方(深圳市九鼎科技,X210)。
uboot根目录下主要文件有:/mkconfig,主Makefile,前者负责uboot的编译,后者负责编译。主要文件夹有:/board,/cpu,/common、/include等,board文件夹中每个子文件夹表示一个开发板,cpu文件夹中每个子文件夹都是一个SoC系列。
x210开发板的uboot的配置与编译步骤。
将源码解压在适当的目录下;
配置,即在uboot的根目录下执行“make x210_sd_config”;
编译,即在uboot的根目录下执行“make”(或者“make -j2”,或者“make -s”,前者多线程编译,后者静默编译)。
整个配置与编译细节流程如下。
1、对配置行为进行分析
之所以要进行配置,是要确定所使用的文件夹、文件的路径。我们在在uboot的根目录下执行“make x210_sd_config”时,x210_sd_config是目标,在主Makefile中2589行有如下代码。
x210_sd_config : unconfig@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
该目标调用MKCONFIG所表示的脚本,即uboot根目录下的mkconfig脚本。该脚本接收6个参数,分别是x210_sd,arm,s5pc11x,x210,samsung,s5pc110;$(@:_config=)表示匹配后面带有_config的参数,并取除去_config的部分,即取x210_sd。
在mkconfig脚本中,创建了一些符号链接,创建了include/config.mk文件(注意这里的config.mk不是根目录下的config.mk文件),创建了include/config.h文件。
其中,创建include/config.mk文件是为了让主Makefile在第133行包含。
# load ARCH, BOARD, and CPU configuration include $(obj)include/config.mk export ARCH CPU BOARD VENDOR SOC
而include/config.h文件中,仅有一行代码,即“#include<configs/x210_sd.h>”。
/* Automatically generated - do not edit */ #include <configs/x210_sd.h>
在进行配置前,configs文件夹就已经在include文件夹里面。configs文件夹里面的每个文件对应一个开发板的头文件,这些头文件都是一些宏定义配置文件,是移植时最主要的文件。
xjh@ubuntu:~/iot/embedded_basic_course/uboot/uboot_jiuding/include/configs# ls x210_nand.h x210_sd.h xjh@ubuntu:~/iot/embedded_basic_course/uboot/uboot_jiuding/include/configs#
从上面可以看出,sd表示inand。x210_sd.h文件被用来生成autoconfig.mk文件,后者又被主Makefile引入,指导整个编译过程。x210_sd.h文件中的宏会影响uboot中的大部分.C文件中的一些条件编译的选择,从而实现最终的可移植性。
2、对uboot主目录下的Makefile文件进行分析
(1)uboot的版本号。(24~29行)
VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = $(obj)include/version_autogenerated.h
(2)确定主机信息然后导出,“export HOSTARCH HOSTOS”。
HOSTARCH、HOSTOS分别表示主机的CPU架构和操作系统。
(3)实现静默编译。指令“make -s”,其中-s表示参数。(50~54行)
(4)两种编译管理方法。(78~123行)
原地编译,即编译得到的文件和源文件在同一个目录下,简单但是会污染源目录;单独文件夹输出的编译,即设置一个输出目录,承载编译输出结果。uboot默认原地编译。我们可以指定具体的输出目录:编译时用“make O=输出目录”;或者先“export BUILD_DIR=输出目录”,然后编译时直接make。
(5)OBJTREE,SRCTREE,TOPDIR。
它们分别表示编译后,.o文件存放的目录的根目录,源码目录的根目录,顶层目录。原地编译时,前者和中者目录是相等的。
(6)MKCONFIG。(101行)
它是Makefile中定义的一个变量,值为源码根目录下的mkconfig,而mkconfig是一个脚本。
(7)“include $(obj)include/config.mk”。(133行)
include/config.mk文件是在配置阶段生成的, 此文件的内容如下。
ARCH = arm CPU = s5pc11x BOARD = x210 VENDOR = samsung SOC = s5pc110
这些配置项的配置值,来自主Makefile第2589行的配置项里的传参。
x210_sd_config : unconfig@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
在主Makefile中的134行将这些变量export出来作为环境变量。
export ARCH CPU BOARD VENDOR SOC
(8)ARCH、CROSS_COMPILE。(136~182行)
这两个是环境变量,ARCH定义为当前编译的目标的CPU架构,在这里是ARM;CROSS_COMPILE定义交叉编译工具的前缀;
3、对uboot主目录下的config.mk文件进行分析
(9)“include $(TOPDIR)/config.mk”。(主Makefile中的185行)
注意这是根目录下的config.mk文件,不是include/config.mk。
(10)编译工具定义。(根目录下的config.mk中的94~107行)
AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm LDR = $(CROSS_COMPILE)ldr STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump RANLIB = $(CROSS_COMPILE)RANLIB
(11)包含开发板配置项目。(根目录下的config.mk中的112行)
# Load generated board configuration sinclude $(OBJTREE)/include/autoconf.mk
autoconf.mk是在配置中自动生成的,它是一些宏,指导编译进行方向。它的配置原料是include/configs/x210_sb.h,include/configs下的每个头文件对应一个开发板。
(12)链接脚本。(在根目录下的config.mk中的142~149行)
如果定义了CONFIG_NAND_U_BOOT,则链接脚本是u-boot-nand.lds,没有定义则链接脚本为u-boot.lds。u-boot.lds这个脚本位于board\samsung\x210下。
uboot的最终链接地址是在Makefile中用-Ttext xxxx的形式来指定,好像和链接链接脚本没有多大的关联?
(13)TEXT_BASE。(在根目录下的config.mk中的156~158行)
为整个uboot链接时指定链接地址。
(14)自动推导规则。(在根目录下的config.mk中的239~256行)
(15)整个Makefile的第一个目标ALL。(在主Makefile中第291行)
其实我们make时,就是make ALL。
综上所述,整个配置和编译过程涉及的文件主要有:主目录下的Makefile文件、根目录下的config.mk文件(被主Makefile文件调用),根目录下的mkconfig文件(配置阶段的配置脚本)。