UBOOT编译--- UBOOT编译过程目标依赖分析(八)
1. 前言
UBOOT版本:uboot2018.03,开发板myimx8mmek240。
2. 概述
本文采用自顶向下的方法,从顶层目标开始到最原始的依赖。
3. u-boot编译
uboot的编译分为两步:配置、编译。
- 配置,执行make pmyimx8mmek240-8mm-2g_defconfig进行配置,在生成.config文件;
- 编译,执行make进行编译,生成u-boot*、System.map等。
4. u-boot编译过程涉及的目标分析
# 顶层Makefile # If building an external module we do not care about the all: rule # but instead _all depend on modules PHONY += all //伪目标all ifeq ($(KBUILD_EXTMOD),) //假设未定义KBUILD_EXTMOD _all: all //_all 是顶层Makefile第一个目标,依赖是all else _all: modules endif ...... all: $(ALL-y) cfg //all自身依赖于$(ALL-y)和cfg ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y) @echo "===================== WARNING ======================" @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove" @echo "(possibly in a subsequent patch in your series)" @echo "before sending patches to the mailing list." @echo "====================================================" endif @# Check that this build does not use CONFIG options that we do not @# know about unless they are in Kconfig. All the existing CONFIG @# options are whitelisted, so new ones should not be added. $(call cmd,cfgcheck,u-boot.cfg)
4.1 目标$(ALL-y)
# 顶层Makefile # Read in config -include include/config/auto.conf ...... -include include/autoconf.mk ...... # Always append ALL so that arch config.mk's can add custom ones ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map binary_size_check ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin //include/config/auto.conf中未定义 ifeq ($(CONFIG_SPL_FSL_PBL),y) //include/config/auto.conf中未定义 ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin else ifneq ($(CONFIG_SECURE_BOOT), y) //include/config/auto.conf中未定义 # For Secure Boot The Image needs to be signed and Header must also # be included. So The image has to be built explicitly ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl endif endif ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin //关注:include/config/auto.conf中有定义 ifeq ($(CONFIG_MX6)$(CONFIG_SECURE_BOOT), yy) //include/config/auto.conf中未定义 ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot-ivt.img else ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img //关注:include/config/auto.conf中有定义 endif ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin //include/config/auto.conf中未定义 ALL-$(CONFIG_OF_SEPARATE) += u-boot.dtb //关注:include/config/auto.conf中有定义 ifeq ($(CONFIG_SPL_FRAMEWORK),y) //关注:include/config/auto.conf中有定义 ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img //关注:include/config/auto.conf中有定义 endif ALL-$(CONFIG_OF_HOSTFILE) += u-boot.dtb //include/config/auto.conf中未定义 ifneq ($(CONFIG_SPL_TARGET),) //include/config/auto.conf中未定义 ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%) endif ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf //关注:include include/autoconf.mk中有定义 ALL-$(CONFIG_EFI_APP) += u-boot-app.efi //include/config/auto.conf中未定义 ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi //include/config/auto.conf中未定义 ifneq ($(BUILD_ROM)$(CONFIG_BUILD_ROM),) //include/config/auto.conf中未定义 ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom endif # enable combined SPL/u-boot/dtb rules for tegra ifeq ($(CONFIG_TEGRA)$(CONFIG_SPL),yy) //include/config/auto.conf中未定义 ALL-y += u-boot-tegra.bin u-boot-nodtb-tegra.bin ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin endif # Add optional build target if defined in board/cpu/soc headers ifneq ($(CONFIG_BUILD_TARGET),) //include/config/auto.conf中未定义 ALL-y += $(CONFIG_BUILD_TARGET:"%"=%) endif ifneq ($(CONFIG_SYS_INIT_SP_BSS_OFFSET),) //include/config/auto.conf中未定义 ALL-y += init_sp_bss_offset_check endif
$(ALL-y)目标除了第一行的通用目标外,其余的目标的定义都只有在特定平台下才成立,这里的注释只针对我当前使用的开发板。要特别注意的是上面的宏定义来源于include/config/auto.conf和include include/autoconf.mk(注意:-include include/config/auto.conf、include include/autoconf.mk这两句话),而上述头文件又来源于执行make pmyimx8mmek240-8mm-2g_defconfig时生成的 .config,详解参见前几篇文章UBOOT编译--- include/config/auto.conf、 include/config/auto.conf.cmd、 include/generated/autoconf.h (二)、UBOOT编译--- include/config.h、 include/autoconf.mk、include/autoconf.mk.dep、u-boot.cfg(三)。
综上:ALL-y 的定义汇总如下:
ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map binary_size_check ALL-y += spl/u-boot-spl.bin ALL-y += u-boot.img ALL-y += u-boot.dtb ALL-y += u-boot-dtb.img ALL-y += u-boot.elf
4.1.1 目标u-boot.bin
ifeq ($(CONFIG_MULTI_DTB_FIT),y)//未定义 fit-dtb.blob: dts/dt.dtb FORCE $(call if_changed,mkimage) MKIMAGEFLAGS_fit-dtb.blob = -f auto -A $(ARCH) -T firmware -C none -O u-boot \ -a 0 -e 0 -E \ $(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) -d /dev/null u-boot-fit-dtb.bin: u-boot-nodtb.bin fit-dtb.blob $(call if_changed,cat) u-boot.bin: u-boot-fit-dtb.bin FORCE $(call if_changed,copy) else ifeq ($(CONFIG_OF_SEPARATE),y) //对DEVICE_TREE的支持(CONFIG_OF_SEPARATE) u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE $(call if_changed,cat) u-boot.bin: u-boot-dtb.bin FORCE $(call if_changed,copy) else u-boot.bin: u-boot-nodtb.bin FORCE $(call if_changed,copy) endif
因为我们打开了DEVICE_TREE的支持,因此u-boot.bin的依赖关系如下:
u-boot-nodtb.bin: u-boot FORCE $(call if_changed,objcopy) $(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE)) $(BOARD_SIZE_CHECK) dts/dt.dtb: u-boot $(Q)$(MAKE) $(build)=dts dtbs u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE $(call if_changed,cat) u-boot.bin: u-boot-dtb.bin FORCE //u-boot.bin $(call if_changed,copy)
可以看到u-boot.bin的依赖有u-boot-dtb.bin 和FORCE ,u-boot-dtb.bin 的依赖有u-boot-nodtb.bin和dts/dt.dtb:
(1)u-boot-nodtb.bin的依赖有u-boot 和 FORCE;
(2)dts/dt.dtb的依赖有u-boot;
4.1.2 目标u-boot.srec、u-boot.sym、System.map
u-boot.hex u-boot.srec: u-boot FORCE $(call if_changed,objcopy) ...... u-boot.sym: u-boot FORCE $(call if_changed,sym) ...... System.map: u-boot @$(call SYSTEM_MAP,$<) > $@
以上三个目标的依赖都是u-boot。
4.1.3 目标binary_size_check
binary_size_check: u-boot-nodtb.bin FORCE @file_size=$(shell wc -c u-boot-nodtb.bin | awk '{print $$1}') ; \ map_size=$(shell cat u-boot.map | \ awk '/_image_copy_start/ {start = $$1} /_image_binary_end/ {end = $$1} END {if (start != "" && end != "") print "ibase=16; " toupper(end) " - " toupper(start)}' \ | sed 's/0X//g' \ | bc); \ if [ "" != "$$map_size" ]; then \ if test $$map_size -ne $$file_size; then \ echo "u-boot.map shows a binary size of $$map_size" >&2 ; \ echo " but u-boot-nodtb.bin shows $$file_size" >&2 ; \ exit 1; \ fi \ fi
目标binary_size_check的依赖是u-boot-nodtb.bin,u-boot.nodtb.bin的依赖也是u-boot(在分析u-boot.bin时,已经分析过)。
4.1.4 spl/u-boot-spl.bin
spl/u-boot-spl.bin: spl/u-boot-spl @: spl/u-boot-spl: tools prepare \ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) \ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_TPL_OF_PLATDATA),dts/dt.dtb) $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
4.1.5 u-boot.img、u-boot-dtb.img
u-boot-dtb.img u-boot.img u-boot.kwb u-boot.pbl u-boot-ivt.img: \ //CONFIG_SPL_LOAD_FIT=y $(if $(CONFIG_SPL_LOAD_FIT),u-boot-nodtb.bin dts/dt.dtb,u-boot.bin) FORCE $(call if_changed,mkimage)
CONFIG_SPL_LOAD_FIT在include/config/auto.conf中有定义,因此u-boot-dtb.img和u-boot.img的依赖是u-boot-nodtb.bin 和dts/dt.dtb。
4.1.6 u-boot.dtb
u-boot.dtb: dts/dt.dtb $(call cmd,copy)
u-boot.dtb的依赖是dts/dt.dtb。
4.1.7 u-boot.elf
u-boot.elf: u-boot.bin $(Q)$(OBJCOPY) -I binary $(PLATFORM_ELFFLAGS) $< u-boot-elf.o $(call if_changed,u-boot-elf)
u-boot.elf的依赖是u-boot.bin。
4.2 目标cfg
# 顶层Makefile u-boot.cfg spl/u-boot.cfg tpl/u-boot.cfg: include/config.h FORCE $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf $(@) ...... cfg: u-boot.cfg
依赖include/config.h是一个头文件,该头文件是在配置编译过程中自动生成的,详解参见UBOOT编译--- include/config.h、 include/autoconf.mk、include/autoconf.mk.dep、u-boot.cfg(三)。
5. 目标u-boot的依赖分析
u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples //重点关注(前半部分是提取$(libs-y)尾最后一个‘/’之前的内容,即编译所在目录) libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) u-boot-init := $(head-y) u-boot-main := $(libs-y) ...... u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE +$(call if_changed,u-boot__) ifeq ($(CONFIG_KALLSYMS),y) //未定义 $(call cmd,smap) $(call cmd,u-boot__) common/system_map.o endif ...... # The actual objects are generated when descending, # make sure no implicit rule kicks in $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ; ...... # Handle descending into subdirectories listed in $(vmlinux-dirs) # Preset locale variables to speed up the build process. Limit locale # tweaks to this spot to avoid wrong language settings when running # make menuconfig etc. # Error messages still appears in the original language PHONY += $(u-boot-dirs) $(u-boot-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@
目标u-boot的依赖有三个:$ (u-boot-init)、$ (u-boot-main)、u-boot.lds、FORCE。其中$ (u-boot-init)、$(u-boot-main)和u-boot.lds分别被定义为:
u-boot-init := $(head-y) u-boot-main := $(libs-y) u-boot.lds: $(LDSCRIPT) prepare FORCE $(call if_changed_dep,cpp_lds)
其中 $ (u-boot-init) 和 $ (u-boot-main)又依赖于$ (u-boot-dirs),$ (u-boot-dirs)是$(libs-y)最后一个‘/’之前的内容,即编译所在目录 ‘/’(比如:arch/arm/cpu)。
5.1 $(head-y)
head-y 定义在 arch/arm/Makefile中,其中CPU在我使用的开发板被定义为armv8(include/config/auto.conf中有定义CONFIG_SYS_CPU="armv8",顶层config.mk定义 CPU := $(CONFIG_SYS_CPU:"%"=%))。
# arch/arm/Makefile head-y := arch/arm/cpu/$(CPU)/start.o
因此:
head-y := arch/arm/cpu/armv8/start.o
5.2 依赖$(libs-y)
libs-y定义在顶层的Makefile和arch/arm/Makefile(include arch/$ (ARCH)/Makefile)中。可以发现$(libs-y)被定义为各层驱动目录下build-in.o的集合:
# 顶层Makefile ######################################################################### # U-Boot objects....order is important (i.e. start must be first) HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n) libs-y += lib/ libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/ //board/myzr/common/ libs-$(CONFIG_OF_EMBED) += dts/ libs-y += fs/ libs-y += net/ libs-y += disk/ libs-y += drivers/ libs-y += drivers/dma/ libs-y += drivers/gpio/ libs-y += drivers/i2c/ libs-y += drivers/mtd/ libs-$(CONFIG_CMD_NAND) += drivers/mtd/nand/ libs-y += drivers/mtd/onenand/ libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/ libs-y += drivers/mtd/spi/ libs-y += drivers/net/ libs-y += drivers/net/phy/ libs-y += drivers/pci/ libs-y += drivers/power/ \ drivers/power/domain/ \ drivers/power/fuel_gauge/ \ drivers/power/mfd/ \ drivers/power/pmic/ \ drivers/power/battery/ \ drivers/power/regulator/ libs-y += drivers/spi/ libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/ libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/ libs-$(CONFIG_SYS_FSL_MMDC) += drivers/ddr/fsl/ libs-$(CONFIG_ALTERA_SDRAM) += drivers/ddr/altera/ libs-y += drivers/serial/ libs-y += drivers/usb/cdns3/ libs-y += drivers/usb/dwc3/ libs-y += drivers/usb/common/ libs-y += drivers/usb/emul/ libs-y += drivers/usb/eth/ libs-y += drivers/usb/gadget/ libs-y += drivers/usb/gadget/udc/ libs-y += drivers/usb/host/ libs-y += drivers/usb/musb/ libs-y += drivers/usb/musb-new/ libs-y += drivers/usb/phy/ libs-y += drivers/usb/ulpi/ libs-y += cmd/ libs-y += common/ libs-y += env/ libs-$(CONFIG_API) += api/ libs-$(CONFIG_HAS_POST) += post/ libs-y += test/ libs-y += test/dm/ libs-$(CONFIG_UT_ENV) += test/env/ libs-$(CONFIG_UT_OVERLAY) += test/overlay/ libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/) //board/myzr/myimx8mm libs-y := $(sort $(libs-y)) u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples u-boot-alldirs := $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-)))) libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) //重点关注这句话 ...... # arch/arm/Makefile # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. machine-$(CONFIG_ARCH_ASPEED) += aspeed //未定义 machine-$(CONFIG_ARCH_AT91) += at91 //未定义 machine-$(CONFIG_ARCH_BCM283X) += bcm283x //未定义 machine-$(CONFIG_ARCH_DAVINCI) += davinci //未定义 machine-$(CONFIG_ARCH_EXYNOS) += exynos //未定义 machine-$(CONFIG_ARCH_HIGHBANK) += highbank //未定义 machine-$(CONFIG_ARCH_KEYSTONE) += keystone //未定义 # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD //未定义 machine-$(CONFIG_KIRKWOOD) += kirkwood //未定义 machine-$(CONFIG_ARCH_MESON) += meson //未定义 machine-$(CONFIG_ARCH_MVEBU) += mvebu //未定义 # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA //未定义 # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X //未定义 machine-$(CONFIG_ORION5X) += orion5x //未定义 machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 //未定义 machine-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx //未定义 machine-$(CONFIG_ARCH_SUNXI) += sunxi //未定义 machine-$(CONFIG_ARCH_SNAPDRAGON) += snapdragon //未定义 machine-$(CONFIG_ARCH_SOCFPGA) += socfpga //未定义 machine-$(CONFIG_ARCH_RMOBILE) += rmobile //未定义 machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip //未定义 machine-$(CONFIG_STM32) += stm32 //未定义 machine-$(CONFIG_TEGRA) += tegra //未定义 machine-$(CONFIG_ARCH_UNIPHIER) += uniphier //未定义 machine-$(CONFIG_ARCH_ZYNQ) += zynq //未定义 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) PLATFORM_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs)) libs-y += $(machdirs) //空 libs-y += arch/arm/cpu/$(CPU)/ //arch/arm/cpu/armv8 libs-y += arch/arm/cpu/ libs-y += arch/arm/lib/ ifeq ($(CONFIG_SPL_BUILD),y) //KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD 注意不是所有开发板都有该定义 ifneq (,$(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_MX35)$(filter $(SOC), mx25 mx5 mx6 mx7 mx35 imx8m imx8)) //SOC=imx8m libs-y += arch/arm/mach-imx/ //成立 endif else ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx7ulp mx31 mx35 mxs imx8 imx8m vf610)) libs-y += arch/arm/mach-imx/ //成立 endif endif ifneq (,$(filter $(SOC), kirkwood)) libs-y += arch/arm/mach-mvebu/ //不成立 endif
其中libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) 这句话是将所有lib-y对应的目录后面补一个built-in.o,最终展开为:
libs-y= arch/arm/cpu/built-in.o \ arch/arm/cpu/armv8/built-in.o \ arch/arm/lib/built-in.o \ arch/arm/mach-imx/built-in.o \ board/myzr/common/built-in.o \ board/myzr/myimx8mm/built-in.o \ cmd/built-in.o \ common/built-in.o \ disk/built-in.o \ drivers/built-in.o \ drivers/dma/built-in.o \ drivers/gpio/built-in.o \ drivers/i2c/built-in.o \ drivers/mtd/built-in.o \ drivers/mtd/onenand/built-in.o \ drivers/mtd/spi/built-in.o \ drivers/net/built-in.o \ drivers/net/phy/built-in.o \ drivers/pci/built-in.o \ drivers/power/built-in.o \ drivers/power/battery/built-in.o \ drivers/power/domain/built-in.o \ drivers/power/fuel_gauge/built-in.o \ drivers/power/mfd/built-in.o \ drivers/power/pmic/built-in.o \ drivers/power/regulator/built-in.o \ drivers/serial/built-in.o \ drivers/spi/built-in.o \ drivers/usb/cdns3/built-in.o \ drivers/usb/common/built-in.o \ drivers/usb/dwc3/built-in.o \ drivers/usb/emul/built-in.o \ drivers/usb/eth/built-in.o \ drivers/usb/gadget/built-in.o \ drivers/usb/gadget/udc/built-in.o \ drivers/usb/host/built-in.o \ drivers/usb/musb-new/built-in.o \ drivers/usb/musb/built-in.o \ drivers/usb/phy/built-in.o \ drivers/usb/ulpi/built-in.o \ env/built-in.o \ fs/built-in.o \ lib/built-in.o \ net/built-in.o \ test/built-in.o \ test/dm/built-in.o
5.3 依赖u-boot.lds
依赖u-boot.lds的定义位于顶层Makefile中:
# 顶层config.mk CPUDIR=arch/$(ARCH)/cpu$(if $(CPU),/$(CPU),)//arch/arm/cpu/armv8 # 顶层Makefile # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. ifndef LDSCRIPT #LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug ifdef CONFIG_SYS_LDSCRIPT //不成立 # need to strip off double quotes LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%) endif endif # If there is no specified link script, we look in a number of places for it ifndef LDSCRIPT ifeq ($(wildcard $(LDSCRIPT)),) LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds //不存在 endif ifeq ($(wildcard $(LDSCRIPT)),) LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot.lds //存在 arch/arm/cpu/armv8/u-boot.lds endif ifeq ($(wildcard $(LDSCRIPT)),) LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot.lds endif endif ...... u-boot.lds: $(LDSCRIPT) prepare FORCE $(call if_changed_dep,cpp_lds)
如果没有定义LDSCRIPT和CONFIG_SYS_LDSCRIPT,则默认使用u-boot自带的lds文件,包括board/$ (BOARDDIR)和$ (CPUDIR)目录下定制的针对board或cpu的lds文件;如果没有定制的lds文件,则采用arch/$(ARCH)/cpu目录下默认的lds文件。
7. prepare系列目标依赖
prepare是一系列prepare伪目标和动作的组合,完成编译前的准备工作,它的相关的定义如下
# Things we need to do before we recursively start building the kernel # or the modules are listed in "prepare". # A multi level approach is used. prepareN is processed before prepareN-1. # archprepare is used in arch Makefiles and when processed asm symlink, # version.h and scripts_basic is processed / created. # Listed in dependency order PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 # prepare3 is used to check if we are building in a separate output directory, # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) prepare3: include/config/uboot.release ifneq ($(KBUILD_SRC),) @$(kecho) ' Using $(srctree) as source for U-Boot' $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \ echo >&2 " $(srctree) is not clean, please run 'make mrproper'"; \ echo >&2 " in the '$(srctree)' directory.";\ /bin/false; \ fi; endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile prepare1: prepare2 $(version_h) $(timestamp_h) \ include/config/auto.conf ifeq ($(wildcard $(LDSCRIPT)),) @echo >&2 " Could not find linker script." @/bin/false endif archprepare: prepare1 scripts_basic prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. # All the preparing.. prepare: prepare0
伪目标prepare依赖prepare0,prepare0又依赖 archprepare、FORCE,archprepare又依赖prepare1和scripts_basic(UBOOT编译--- make xxx_deconfig过程详解(一) 4.1小节 - 依赖 scripts_basic):
1. 在prepare1的依赖列表中,除了include/config/auto.conf之外,还有$ (version_h)和$(timestamp_h),它们的依赖关系如下:
version_h := include/generated/version_autogenerated.h timestamp_h := include/generated/timestamp_autogenerated.h $(version_h): include/config/uboot.release FORCE $(call filechk,version.h) $(timestamp_h): $(srctree)/Makefile FORCE $(call filechk,timestamp.h)
(1)其中include/config/auto.conf具体分析参见:UBOOT编译--- include/config/auto.conf、 include/config/auto.conf.cmd、 include/generated/autoconf.h (二);
(2)其中version_h和timestamp_h具体分析参见:UBOOT编译--- UBOOT的$(version_h) $(timestamp_h)(七)
2. 在prepare2的依赖列表中有prepare3 和 outputmakefile;
(1)其中outputmakefile具体分析参见:UBOOT编译--- make xxx_deconfig过程详解(一) 4.2小节 - 依赖 outputmakefile。
3. prepare3的依赖include/config/uboot.release
# Store (new) UBOOTRELEASE string in include/config/uboot.release include/config/uboot.release: include/config/auto.conf FORCE $(call filechk,uboot.release)
(1)其中include/config/uboot.release具体分析参见:UBOOT编译--- UBOOT的$(version_h) $(timestamp_h)(七) - 3.1.1 依赖include/config/uboot.release;
8. _all目标依赖关系简图
--------------------------------------------| | arch/arm/cpu \ $(u-boot-dirs)| arch/arm/cpu/built-in.o \ | arch/arm/cpu/armv8 \ 的值 | arch/arm/cpu/armv8/built-in.o \ | arch/arm/lib \ | arch/arm/lib/built-in.o \ | arch/arm/mach-imx \ | arch/arm/mach-imx/built-in.o \ | board/myzr/common \ | board/myzr/common/built-in.o \ | board/myzr/myimx8mm \ | board/myzr/myimx8mm/built-in.o \ | cmd \ | cmd/built-in.o \ | common \ | common/built-in.o \ | disk \ | disk/built-in.o \ | drivers \ | drivers/built-in.o \ | drivers/dma \ | drivers/dma/built-in.o \ | drivers/gpio \ | drivers/gpio/built-in.o \ | drivers/i2c \ | include/config/auto.conf scripts_basic drivers/i2c/built-in.o \ | drivers/mtd \ | \ / drivers/mtd/built-in.o \ | drivers/mtd/onenand \ | \ / drivers/mtd/onenand/built-in.o \ | drivers/mtd/spi \ | \ / drivers/mtd/spi/built-in.o \ | drivers/net \ | scripts prepare drivers/net/built-in.o \ | drivers/net/phy \ | ----- ----- drivers/net/phy/built-in.o \ | . | \ / . | . | \ / . | . | \ / . | env \ | \ / env/built-in.o \ | fs \ | $(u-boot-dirs) fs/built-in.o \ | lib \ | ------------------------- lib/built-in.o \ | net \ | | \ net/built-in.o \ | test \ | | \ test/built-in.o \ | test/dm | | 依赖 \ test/dm/built-in.o --------------------------------------------- | \ || include/config/uboot.release | \ || arch/arm/cpu/armv8/u-boot.lds | | \ || || outputmakefile prepare3 $(u-boot-init)==$(head-y) $(u-boot-main)== u-boot.lds FORCE \ / arch/arm/cpu/armv8/start.o $(libs-y) / / \ / \ | / / \ / \ | / / \ / \ | / / \ / include/generated/version_autogenerated.h include/generated/timestamp_autogenerated.h \ | / / \ / | / \ | / / \ / | / ---------------------------------------------- prepare2 $(version_h) $(timestamp_h) include/config/auto.conf(auto.conf里去掉了.config中的注释项目以及空格行,其它的都一样) | \ \ / / | \ \ / / u-boot \ \ / / --------------------------------------------------------------------------------------- \ \ / / / / \ \ \ ------------------------------------------- / / \ \ \ prepare1 scripts_basic / | \ \ \ ------- ------------- | | | | | \ / | dts/dt.dtb | | | \ / | -------------------------- | | | ----------------------------------------- | / / | | | | archprepare u-boot-nodtb.bin / / | | | | ---------- --------------- / / | | | | | | \ \ / / | | | | | | \ \/ / | | | | prepare0 | \ /\ / | | | | -------- | \ / \ / | | | | | | \/ \-------\ / | | | | | | /\ \ / | | | | tools prepare | / \ \ / | | | | ----- ----- | / \ \/ | | | | \ / u-boot-dtb.bin \ /\ | | | | \ / -------------- \ / \-----------\ | | | | \ / | \ / \ | | | | \ / | \ / \| | | | spl/u-boot-spl | \ / \ | | | -------------- | \ / |\--------------| | | | | | \/ | | | | | | u-boot.bin u-boot.img/u-boot-dtb.img u-boot.dtb binary_size_check u-boot.srec u-boot.sym System.map spl/u-boot-spl.bin ---------- -------------------------- --------- ----------------- ----------- --------- -------- ----------------- / | | | | | | | | / | | | | | | | | / | | | | | | | | u-boot.elf | | | | | | | | --------- | | | | | | | | \ | | | | | | | | \ | | | | | | | | \ \ \ | / / / / / include/config.h \ \ \ | / / / / / | \ \ \ | / / / / / | \ \ \ | / / / / / | \ \ \ | / / / / / | \ \ \ | / / / / / u-boot.cfg \ \ \ | / / / / / | \ \ \ | / / / / / | ---------------------------------------------------------------------------------------------------------- | $(ALL-y) cfg \ / \ / \ / ----------------------------------------------------------------------------------------------------- all | _all
9. 总结
本文来自博客园,作者:BSP-路人甲,转载请注明原文链接:https://www.cnblogs.com/jianhua1992/p/16852768.html,并保留此段声明,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通