UBOOT版本:uboot2018.03,开发板myimx8mmek240。
本文采用自顶向下的方法,从顶层目标开始到最原始的依赖。
uboot的编译分为两步:配置、编译。
# 顶层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)
# 顶层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
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;
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。
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时,已经分析过)。
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
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。
u-boot.dtb: dts/dt.dtb
$(call cmd,copy)
u-boot.dtb的依赖是dts/dt.dtb。
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。
# 顶层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(三)。
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)。
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
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
依赖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文件。
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;
--------------------------------------------|
| 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
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
有什么方法可以告诉sidekiq一项工作依赖于另一项工作,并且在后者完成之前无法开始? 最佳答案 仅使用Sidekiq;答案是否定的。正如DickieBoy所建议的那样,您应该能够在依赖作业完成时将其启动。像这样。#app/workers/hard_worker.rbclassHardWorkerincludeSidekiq::Workerdefperform()puts'Doinghardwork'LazyWorker.perform_async()endend#app/workers/lazy_worker.rbclassLaz
是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/
关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭10年前。ImprovethisquestionLinux专家正在转向Mac(10.8)。因为我懒...我使用MacPorts安装MacVim。它似乎安装没有错误。我只需要mvim中的python、ruby和perl支持。$/opt/local/bin/mvim--version|egrep'patches|python|ruby|perl'Includedpatches:1-244,246-646+multi_lang-mzscheme+
我已经开始学习Ruby,我已经阅读了一些教程,甚至还买了一本书(“ProgrammingRuby1.9-ThePragmaticProgrammers'Guide”),我遇到了一些以前从未见过的新东西使用我知道的任何其他语言(我是一名PHP网络开发人员)。block和过程。我想我明白它们是什么,但我不明白的是为什么它们如此伟大,以及我应该在何时何地使用它们。我到处都看到他们说block和过程是Ruby中的一个很棒的特性,但我不理解它们。这里有人能给像我这样的Ruby新手一些解释吗? 最佳答案 block有很多好处。电梯演讲:bloc
当我刚刚运行middleman时服务,all.css编译得很好,只包含对+box-shadow(none)的调用:/*line1,/home/yang/asdf/source/stylesheets/content.css.sass*/div{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}但是当我构建网站时,我得到了这个Sass/Compass错误:$middlemanbuildSlim::EmbeddedEngineisdeprecated,itiscalledSlim::EmbeddedinSlim2.0
目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标