IMX6ULL 学习笔记
version : v1.0 「2023.4.27」
author: Y.Z.T.
简介: 随记 , 记录 I.MX6ULL 系列 SOC 的uboot 编译过程
⭐️ 目录
文章目录
2.2 Uboot 编译
编译uboot
的过程中 使用了三条命令
make distclean #删除之前的配置文件
make mx6ull_14x14_ddr512_emmc_defconfig # 配置 uboot,生成.config 文件
make # 编译
2.2.1 make distclean
用于删除之前的uboot配置信息
distclean: mrproper
@find $(srctree) $(RCS_FIND_IGNORE) \
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-o -name '.*.rej' -o -name '*%' -o -name 'core' \
-o -name '*.pyc' \) \
-type f -print | xargs rm -f
@rm -f boards.cfg
2.2.2. make xxx_defconfig
配置
uboot
,生成.config
文件
#最终要执行的脚本
config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
%config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
else
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.
ifeq ($(dot-config),1)
# Read in config
-include include/config/auto.conf
....
- 可以看到目标
%config
有三个 依赖目标scripts_basic
、outputmakefile
、FORCE
FORCR
PHONY += FORCE
FORCE:
- 可以看到
FORCE
是没有规则和依赖的,所以每次都会重新生成FORCE
- 当
FORCE
作为其他目标的依赖时,由于FORCE
总是被更新过的,因此依赖所在的规则总是会执行的。
outputmakefile
PHONY += outputmakefile
# outputmakefile generates a Makefile in the output directory, if
# using a separate output directory. This allows convenient use of
# make in the output directory.
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif
- 可以看到 判断
KBUILD_SRC
是否为空 , 只有变量KBUILD_SRC
不为空的时候 ,outputmakefile
才有意义- 一般都是设置
KBUILD_SRC
为空 , 所以outputmakefile
无效。
scripts_basic
# Basic helpers built in scripts/
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
# To avoid any implicit rule to kick in, define an empty command.
scripts/basic/%: scripts_basic ;
在
scripts_basic:
的命令中$(Q)
是表示 是否输出完整命令 这里Q = @
或Q = 空
$(MAKE) = make
变量
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
- 变量
$(srctree)
为.
表示当前目录则
scripts_basic
展开后为scripts_basic: @make -f ./scripts/Makefile.build obj=scripts/basic #也可以没有@,视配置而定 @rm -f . tmp_quiet_recordmcount #也可以没有@
可以看到在
%config
的三个依赖中 , 只有scripts_basic
是起作用了
因此%config
对应的规则展开如下
make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
则命令 make xxx_defconfig
执行流程 如下
2.2.3 make
编译
uboot
,生成二进制的u-boot.bin
文件和其他的一些与uboot
有关的文件,比如u-boot.imx
等等
make 执行流程
2.2.3.1 默认目标 _all
使用
make
命令后 , 由于没有指明目标 , 所以会使用默认目标_all
# That's our default target when none is given on the command line
PHONY := _all
_all:
2.2.3.2 _all的依赖 all
默认目标
_all
的依赖 为all
# If building an external module we do not care about the all: rule
# but instead _all depend on modules
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
_all: all
else
_all: modules
endif
KBUILD_EXTMOD
是用于 指定是否 单独编译模块 , 这里一般都是KBUILD_EXTMOD = 空
- 则这里
_all
的依赖就是all
2.2.3.3 all 的依赖 ALL-y
通过查看
all
的规则可以知道 ,all
的依赖为ALL-y
all: $(ALL-y)
ifneq ($(CONFIG_SYS_GENERIC_BOARD),y)
@echo "===================== WARNING ======================"
@echo "Please convert this board to generic board."
@echo "Otherwise it will be removed by the end of 2014."
@echo "See doc/README.generic-board for further information"
@echo "===================================================="
endif
ifeq ($(CONFIG_DM_I2C_COMPAT),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
2.2.3.4 $(ALL-y) 的具体规则
ALL-y
主要包含u-boot.srec
、u-boot.bin
、u-boot.sym
、System.map
、u-boot.cfg
和binary_size_check
这几个文件。根据uboot
的配置情况也可能包含其他的文件ALL-y
里面有个u-boot.bin
,这个就是我们最终需要的uboot
二进制可执行文件
# 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 u-boot.cfg binary_size_check
ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
ifeq ($(CONFIG_SPL_FSL_PBL),y)
ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin
else
ifneq ($(CONFIG_SECURE_BOOT), y)
# 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
ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img
ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin
ALL-$(CONFIG_OF_SEPARATE) += u-boot.dtb
ifeq ($(CONFIG_SPL_FRAMEWORK),y)
ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img
endif
ALL-$(CONFIG_OF_HOSTFILE) += u-boot.dtb
ifneq ($(CONFIG_SPL_TARGET),)
ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
endif
ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi
ifneq ($(BUILD_ROM),)
ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
endif
# enable combined SPL/u-boot/dtb rules for tegra
ifeq ($(CONFIG_TEGRA)$(CONFIG_SPL),yy)
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),)
ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
endif
2.2.3.5 u-boot.bin
的 依赖 u-boot-nodtb.bin
最终可执行文件
u-boot.bin
的依赖为u-boot-nodtb.bin
u-boot-nodtb.bin: u-boot FORCE
$(call if_changed,objcopy)
$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
$(BOARD_SIZE_CHECK)
- 可以看到
u-boot-nodtb.bin
又依赖于u-boot
2.2.3.6 u-boot 的规则
u-boot
的具体规则如下
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
$(u-boot-main)
就等于所有子目录中built-in.o
的集合- 这个规则就相当于将以
u-boot.lds
为链接脚本,将arch/arm/cpu/armv7/start.o
和各个子目录下的built-in.o
链接在一起生成u-boot
- 表现在程序上最终是用
arm-linux-gnueabihf-ld.bfd
命令将arch/arm/cpu/armv7/start.o
和其他众多的built_in.o
链接在一起,形成u-boot