08_Uboot顶层Makefile分析_make过程

文章详细阐述了U-Boot的make编译过程,从all目标的依赖开始,逐步解析了如何通过KBUILD_EXTMOD、ALL-y等变量,以及makefile中的规则和函数,生成最终的u-boot.bin二进制文件。这个过程涉及到配置文件.config、源码编译、链接脚本u-boot.lds,以及如何通过ld命令将多个.o文件链接成u-boot。
摘要由CSDN通过智能技术生成

目录

make 过程


make 过程

配置好 uboot 以后就可以直接make 编译了,因为没有指明目标,所以会使用默认目标,主 Makefile 中的默认目标如下:

 目标_all 又依赖于all,如下所示:

如果KBUILD_EXTMOD为空的话_all 依 赖 于all 。这 里 不 编 译 模 块,所 以KBUILD_EXTMOD肯定为空,_all 的依赖就是all。在主 Makefileall目标规则如下:

802行可以看出,all目标依赖$(ALL-y),而在顶层Makefile中,ALL-y如下:

 从示例代码代码可以看出,ALL-y 包含 u-boot.srecu-boot.binu-boot.sym、System.map、u-boot.cfg binary_size_check 这几个文件。根据 uboot 的配置情况也可能包含其 他的文件,比如:

ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin 

CONFIG_ONENAND_U_BOOT就是uboot中跟ONENAND配置有关的,如果我们使能ONENAND,那么在.config 配置文件中就会有“CONFIG_ONENAND_U_BOOT=y”这一句。相 当于 CONFIG_ONENAND_U_BOOT 是个变量,这个变量的值为“y”,所以展开以后就是:

 ALL-y += u-boot-onenand.bin

这个就是.config 里面的配置参数的含义,这些参数其实都是变量,后面跟着变量值,会在 顶层 Makefile 或者其他 Makefile 中调用这些变量。

ALL-y 里面有个u-boot.bin,这个就是我们最终需要的uboot二进制可执行文件,所作的所有工作就是为了它。在顶层Makefile中找到u-boot.bin目标对应的规则,如下所示:

825行判断CONFIG_OF_SEPARATE是否等于y如果相等,那条件就成立,在.config中搜索“CONFIG_OF_SEPARAT”,没有找到,说明条件不成立。

832行就是目标u-boot.bin的规则,目标u-boot.bin依赖于u-boot-nodtb.bin,命令为$(call if_changed,copy) ,这里调用了 if_changed ,if_changed是一个函数, 这个函数在scripts/Kbuild.include中有定义,而顶层Makefile中会包含scripts/Kbuild.include 文件,这个前面已经说过了。if_changed 在 Kbuild.include 中的定义如下: 

 第227行为if_changed的描述,根据描述,在一些先决条件比目标新的时候,或者命令行 有改变的时候,if_changed就会执行一些命令。

257行就是函数if_changed,if_changed函数引用的变量比较多,也比较绕,我们只需要知道它可以从u-boot-nodtb.bin生成u-boot.bin就行了。

既然u-boot.bin依赖于u-boot-nodtb.bin,那么肯定要先生成u-boot-nodtb.bin文件,顶层Makefile中相关代码如下:

 目标u-boot-nodtb.bin又依赖于u-boot,顶层Makefileu-boot相关规则如下:

 目标u-boot依赖于u-boot_initu-boot-mainu-boot.ldsu-boot_initu-boot-main是两个变量,在顶层Makefile中有定义,值如下:

$(head-y)CPU架构有关,我们使用的是ARM芯片,所以head-yarch/arm/Makefile中被指定为:

head-y := arch/arm/cpu/$(CPU)/start.o

根据分析,我们知道CPU=armv7,因此head-y展开以后就是:

 head-y := arch/arm/cpu/armv7/start.o

因此: 

u-boot-init= arch/arm/cpu/armv7/start.o 

$(libs-y)在顶层Makefile中被定义为uboot所有子目录下build-in.o的集合,代码如下:

从上面的代码可以看出,libs-y都是uboot各子目录的集合,最后:  

libs-y := $(patsubst %/, %/built-in.o, $(libs-y))  

这里调用了函数patsubst,将libs-y中的“/”替换为”/built-in.o”,比如“drivers/dma/”就变为了“drivers/dma/built-in.o”,相当于将libs-y改为所有子目录中built-in.o文件的集合。那么u-boot-main就等于所有子目录中built-in.o的集合。

这个规则就相当于将以u-boot.lds为链接脚本,将arch/arm/cpu/armv7/start.o和各个子目录

下的built-in.o链接在一起生成u-boot

u-boot.lds的规则如下:

接下来的重点就是各子目录下的built-in.o是怎么生成的,以 drivers/gpio/built-in.o为例,在drivers/gpio/目录下会有个名为.built-in.o.cmd 的文件,此文件内容如下:

 从命令“cmd_drivers/gpio/built-in.o”可以看出,drivers/gpio/built-in.o这个文件是使用ld命令由文件 drivers/gpio/mxc_gpio.o生成而来的,mxc_gpio.omxc_gpio.c编译生成的.o文件,这个是NXPI.MX系列的GPIO驱动文件。这里用到了ld的“-r”参数,参数含义如下:

-r –relocateable: 产生可重定向的输出,比如,产生一个输出文件它可再次作为‘ld’的输入,这经常被叫做“部分链接”,当我们需要将几个小的.o文件链接成为一个.o文件的时候,需要使用此选项。最终将各个子目录中的built-in.o文件链接在一起就形成了u-boot,使用如下命令编译uboot就可以看到链接的过程:

 编译的时候会有如图所示内容输出:

 将其整理一下,内容如下:

可以看出最终是用arm-linux-gnueabihf-ld.bfd命令将arch/arm/cpu/armv7/start.o和其他众多的 built_in.o链接在一起,形成 u-boot

目标all除了u-boot.bin以外还有其他的依赖,比如 u-boot.srec u-boot.sym System.mapu-boot.cfgbinary_size_check等等,这些依赖的生成方法和u-boot.bin很类似,大家自行查看 一下顶层 Makefile

 

总结一下“make”命令的流程,如图所示:

 

就是“make”命令的执行流程,关于uboot的顶层Makefile就分析到这里,重点是“make xxx_defconfig”和“make”这两个命令的执行流程:

make xxx_defconfig:用于配置uboot,这个命令最主要的目的就是生成.config 文件。

make:用于编译uboot,这个命令的主要工作就是生成二进制的u-boot.bin文件和其他的一 些与 uboot有关的文件,比如u-boot.imx等等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值