uboot顶层Makefile分析-make的过程分析一

一.  uboot的 make过程

本文来了解一下,uboot的 make 过程。继uboot配置命令执行之后,最终生成 uboot.bin 裸机程序的过程。

之前有了解 uboot的配置过程,即执行 "make xxx_deconfig"命令,主要生成 .config配置文件的过程。不同类型的开发板(即EMMC / Nand-Flash)所用的配置文件不同。

二.  顶层 Makefile -make过程

1. 依赖关系

配置好 uboot 以后就可以直接 make 编译了,因为没有指明目标,所以会使用默认目标。

顶层 Makefile 中的默认目标如下:

128 # That's our default target when none is given on the command line
129 PHONY := _all
130 _all:

(1)  目标_all 依赖规则

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

196 PHONY += all
197 ifeq ($(KBUILD_EXTMOD),)
198 _all: all
199 else
200 _all: modules
201 endif

可以看出,这 里 不 编 译 模 块 , 所 以 KBUILD_EXTMOD 为空,_all 的依赖就是 all

(2)  all 依赖规则

在主 Makefile all依赖于 ALL_y 规则如下:
802 all: $(ALL-y)

(3)  ALL_y 依赖规则

而在顶层 Makefile 中, ALL-y 依赖规则 如下:
731 ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg 
binary_size_check
732
733 ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
734 ifeq ($(CONFIG_SPL_FSL_PBL),y)
735 ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin
736 else
737 ifneq ($(CONFIG_SECURE_BOOT), y)
738 # For Secure Boot The Image needs to be signed and Header must also
739 # be included. So The image has to be built explicitly
740 ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl
741 endif

可以看出,ALL-y 包含 u-boot.srecu-boot.binu-boot.symSystem.mapu-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 中调用这些变量。

(4) uboot.bin 依赖关系

  u-boot.bin,最终是我们需要的 uboot 二进制可执行文件, 所作的所 有工作就是为了它。在顶层 Makefile 中找到 u-boot.bin 目标对应的规则,如下所示:
825 ifeq ($(CONFIG_OF_SEPARATE),y)
826 u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE
827 $(call if_changed,cat)
828
829 u-boot.bin: u-boot-dtb.bin FORCE
830 $(call if_changed,copy)
831 else
832 u-boot.bin: u-boot-nodtb.bin FORCE
833 $(call if_changed,copy)
834 endif

825 行判断 CONFIG_OF_SEPARATE 是否等于 y ,如果相等,那条件就成立,在 .config
中搜索“ CONFIG_OF_SEPARAT ”,没有找到,说明条件不成立。
832 行就是目标 u-boot.bin 的规则,目标 u-boot.bin 依赖于 u-boot-nodtb.bin。

(5) u-boot-nodtb.bin 依赖关系

目标 u-boot-nodtb.bin 又依赖于 u-boot ,顶层 Makefile u-boot 相关规则如下:
1170 u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
1171 $(call if_changed,u-boot__)
1172 ifeq ($(CONFIG_KALLSYMS),y)
1173 $(call cmd,smap)
1174 $(call cmd,u-boot__) common/system_map.o
1175 endif

(6)  u-boot 依赖规则

目标 u-boot 依赖于 u-boot_init u-boot-main u-boot.lds u-boot_init u-boot-main 是两个
变量,在顶层 Makefile 中有定义,规则如下:
678 u-boot-init := $(head-y)
679 u-boot-main := $(libs-y)

(7)  $(head-y) 依赖关系与 $(libs-y) 的依赖关系

$(head-y) CPU 架构有关,我们使用的是 ARM 芯片,所以 head-y arch/arm/Makefile
被指定为:
head-y := arch/arm/cpu/$(CPU)/start.o
我们知道 CPU=armv7 ,因此, head-y 展开以后就是:
head-y := arch/arm/cpu/armv7/start.o

$(libs-y) 在顶层 Makefile 中被定义为 uboot 所有子目录下 build-in.o 的集合,(这里只显示了涉及 $(libs-y) 一部分代码), 代码如下:
620 libs-y += lib/
621 libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
622 libs-$(CONFIG_OF_EMBED) += dts/
623 libs-y += fs/
624 libs-y += net/
625 libs-y += disk/
626 libs-y += drivers/
627 libs-y += drivers/dma/
628 libs-y += drivers/gpio/
629 libs-y += drivers/i2c/
......
660 libs-y += cmd/
661 libs-y += common/
可以看出, 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.lds 为链接脚本,将 arch/arm/cpu/armv7/start.o 和各个子目录
下的 built-in.o 链接在一起生成 u-boot
链接脚本 u-boot.lds 的规则如下:
u-boot.lds: $(LDSCRIPT) prepare FORCE
    $(call if_changed_dep,cpp_lds)

链接脚本 u-boot.lds文件,默认是没有的,编译后才会生成。uboot根目录下的链接脚本文件 u-boot.ld 是由其他文件生成的,通过工程搜索,应该是由 arch\arm\cpu\u-boot.lds生成的。

下一篇文章继续了解 uboot的 make过程。

你可能感兴趣的:(嵌入式C开发,linux,arm开发)