UBOOT编译--- UBOOT编译过程目标依赖分析(八)

2022-12-25,,,,

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. 总结

UBOOT编译--- UBOOT编译过程目标依赖分析(八)的相关教程结束。

《UBOOT编译--- UBOOT编译过程目标依赖分析(八).doc》

下载本文的Word格式文档,以方便收藏与打印。