https://blog.csdn.net/weixin_45309916/article/details/109218569
https://blog.csdn.net/guyongqiangx/article/details/52565493
https://blog.csdn.net/guyongqiangx/article/details/52761678
https://blog.csdn.net/whitefish520/article/details/107635906
https://blog.csdn.net/m0_37761102/article/details/121147426
https://blog.csdn.net/weixin_45309916/article/details/109218569
u-boot目录下的make.sh脚本执行 make PYTHON=python2 CROSS_COMPILE=/home/xinyi/android/code/Task1-debian/rk3588_source/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- all --jobs=16
指令
分析u-boot目录下Makefile文件:
all: $(ALL-y) cfg
变量$(ALL-y)的值为:checkarmreloc u-boot.srec u-boot.bin u-boot.sym System.map binary_size_check spl/u-boot-spl.bin u-boot.img tpl/u-boot-tpl.bin u-boot.dtb u-boot-dtb.img
然后我们看看各个目标又是如何生成的:(以#为层级表示目标)
目录
checkarmreloc(arm重定位前缀检查)
# ARM relocations should all be R_ARM_RELATIVE (32-bit) or
# R_AARCH64_RELATIVE (64-bit).
checkarmreloc: u-boot
@RELOC="`$(CROSS_COMPILE)readelf -r -W $< | cut -d ' ' -f 4 | \
grep R_A | sort -u`"; \
if test "$$RELOC" != "R_ARM_RELATIVE" -a \
"$$RELOC" != "R_AARCH64_RELATIVE"; then \
echo "$< contains unexpected relocations: $$RELOC"; \
false; \
fi
上面代码的意思:利用readelf工具读取u-boot这个文件,按' '截取出第4列,最后得到的结果是R_AARCH64_RELATIVE。
u-boot (强制更新)
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
+$(call if_changed,u-boot__)
上面第二行+号表示什么意思???
看这个if_changed函数,到处都在使用,它定义在scripts/Kbuild.include
文件中
ifneq ($(KBUILD_NOCMDDEP),1)
# Check if both arguments has same arguments. Result is empty string if equal.
# User may override this check using make KBUILD_NOCMDDEP=1
arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
$(filter-out $(cmd_$@), $(cmd_$(1))) )
else
arg-check = $(if $(strip $(cmd_$@)),,1)
endif
# Find any prerequisites that is newer than target or that does not exist.
# PHONY targets skipped in both cases.
any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
# Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
u-boot-init
u-boot-init := $(head-y)
head-y是定义在include arch/$(ARCH)/Makefile中,head-y := arch/arm/cpu/$(CPU)/start.o
u-boot-main
u-boot-main := $(libs-y)
libs-y: arch/arm/cpu/built-in.o arch/arm/cpu/armv8/built-in.o arch/arm/lib/built-in.o arch/arm/mach-rockchip/built-in.o board/rockchip/evb_rk3588/built-in.o cmd/built-in.o common/built-in.o disk/built-in.o drivers/built-in.o drivers/cpu/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/charge/built-in.o drivers/power/domain/built-in.o drivers/power/dvfs/built-in.o drivers/power/fuel_gauge/built-in.o drivers/power/io-domain/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-main依赖着各个模块文件夹下的built-in.o文件
u-boot.lds
u-boot.lds: $(LDSCRIPT) prepare FORCE
$(call if_changed_dep,cpp_lds)
$(LDSCRIPT)为:./arch/arm/cpu/armv8/u-boot.lds
,为链接脚本文件。
prepare
# 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
要点一:
看$(Q)$(MAKE) $(build)=.
这行脚本,到处都有使用,其中build变量定义在scripts/Kbuild.include
文件中.
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj
-f:指定Makefile为 u-boot/scripts/Makefile.build
关于这行脚本$(Q)$(MAKE) $(build)=.
的理解:
http://xinyiworld.top/wordpress_it/?p=8101
要点二:
可以看到prepare的依赖链路为prepare-->prepare0-->archprepare --> prepare1--> prepare2--> prepare3--> prepare1 --> include/config/uboot.release
uboot.release是强制更新的,并且依赖了include/config/auto.conf目标。
include/config/uboot.release: include/config/auto.conf FORCE
0 条评论