yocto uboot编译分析(基于stm32mp1)
环境介绍
软件环境:
repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.10-dunfell-mp1-21-11-17
相关代码路径:
layers/meta-st/meta-st-stm32mp/recipes-bsp/u-boot
编译流程分析
总览
如上图所示,编译的入口是layers/meta-st/meta-st-stm32mp/recipes-bsp/u-boot/u-boot-stm32mp_2020.10.bb 文件
先浏览一下u-boot-stm32mp_2020.10.bb大致内容:
require u-boot-stm32mp-common_${PV}.inc
require u-boot-stm32mp.inc
SUMMARY = "Universal Boot Loader for embedded devices for stm32mp"
LICENSE = "GPLv2+"
PROVIDES += "u-boot"
RPROVIDES_${PN} += "u-boot"
# ---------------------------------
# Configure archiver use
# ---------------------------------
include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'u-boot-stm32mp-archiver.inc','')}
可以看到实际上除了包含三个引用文件以外只提供了一个PROVIDES。而且其实在machine的st-machine-providers-stm32mp.inc 配置里面也有如下配置:
PREFERRED_PROVIDER_virtual/bootloader = "u-boot-stm32mp"
PREFERRED_PROVIDER_u-boot = "u-boot-stm32mp"
所以我们可以使用如下三个个命令编译uboot都是可以的:
bitbake u-boot-stm32mp
bitbake u-boot
bitbake virtual/bootloader
详细编译流程
所以uboot编译的重点就是上面说到的三个引用文件:
u-boot-stm32mp-common_${PV}.inc
u-boot-stm32mp.inc
u-boot-stm32mp-archiver.inc
其实还有一个machine conf里面的配置文件:st-machine-common-stm32mp.inc
- st-machine-common-stm32mp.inc
首先我们先看下st-machine-common-stm32mp.inc里面涉及到uboot比较重要的配置内容:(整理以后)
- UBOOT_CONFIG = trusted_stm32mp15 basic_stm32mp15
- UBOOT_CONFIG[basic_stm32mp15]= “stm32mp15_basic_defconfig,u-boot.img”
- UBOOT_CONFIG[trusted_stm32mp15] = “stm32mp15_trusted_defconfig,u-boot.stm32”
- UBOOT_DEVICETREE = “${STM32MP_DEVICETREE}”
- ST_UBOOT_DEBUG_TRACE=1
可以看到最主要的就是指定uboot配置和编译过程中使用的config文件和dts文件,以及调试符号表使能开关
- u-boot-stm32mp-common_${PV}.inc
本文件相对比较简单,主要就是设置菜谱的一些属性,包括:
- DEPENDS: 指定依赖
- SRC_URI : 指定源和patch
- SRCREV : 指定特定的节点
- PV : 指定版本号
- S : 指定源码路径
- u-boot-stm32mp.inc
该文件引入了标准的uboot编译指导文件require recipes-bsp/u-boot/u-boot.inc,然后在此基础上定制了几个func,下面简单介绍下这几个func的功能,具体内容可以看源码:
- do_configure_prepend
如果配置生成的镜像文件是.stm32后缀,则向config文件中追加 CONFIG_STM32MP15x_STM32IMAGE=y 配置项 - do_configure_append
检查是否支持nor nand启动,如果支持则在配置以后生成的.config文件中追加分区相关的配置信息,我支持sdcard和emmc启动,故本func没有做任何处理 - do_compile_append
因为ST适配多芯片多评估板,所以他的STM32MP_DEVICETREE 变量会配置比较多,在uboot编译完成以后会继续检查STM32MP_DEVICETREE变量,会继续编译出STM32MP_DEVICETREE变量里面的dtb文件和镜像文件 - do_deploy_append
部署会根据你的UBOOT_CONFIG UBOOT_DEVICETREE两个变量来决定上一步do_compile_append 编译出来的那么多dtb和bin文件到底安装哪几个到实际的image下
- u-boot-stm32mp-archiver.inc
u-boot-stm32mp-archiver.inc实际上就是根据上面的配置生成一个Makefile.sdk文件,合并后的文件详细内容如下所示:
# Set default path
SRC_PATH ?= $(PWD)
BLD_PATH ?= $(SRC_PATH)/../build
DEPLOYDIR ?= $(SRC_PATH)/../deploy
# Remove default variables
LDFLAGS =
CFLAGS =
CPPFLAGS =
UBOOT_LOCALVERSION =
# Configure default U-Boot configs
UBOOT_CONFIGS ?= stm32mp15_trusted_defconfig,trusted,u-boot.dtb stm32mp15_basic_defconfig,basic,u-boot.img
DEVICE_TREE ?= stm32mp157a-dk1 stm32mp157d-dk1 stm32mp157c-dk2 stm32mp157f-dk2 stm32mp157c-ed1 stm32mp157f-ed1 stm32mp157a-ev1 stm32mp157c-ev1 stm32mp157d-ev1 stm32mp157f-ev1
# Configure default fip feature
ENABLE_FIP ?= "1"
help:
@echo
@echo "Configured U-Boot config(s):"
@for config in $(UBOOT_CONFIGS); do \
defconfig=$$(echo $$config | cut -d',' -f1) ; \
type=$$(echo $$config | cut -d',' -f2) ; \
binary=$$(echo $$config | cut -d',' -f3) ; \
echo " $$defconfig config ($$type type) for $$binary binary" ; \
for devicetree in $(DEVICE_TREE); do \
echo " with device tree: $$devicetree" ; \
done ; \
done
@echo
@echo "U-Boot folder configuration:"
@echo " SRC_PATH = $(SRC_PATH)"
@echo " BLD_PATH = $(BLD_PATH)"
@echo " DEPLOYDIR = $(DEPLOYDIR)"
@echo
@echo "FIP configuration:"
@echo " ENABLE_FIP = $(ENABLE_FIP) ('1' to generate fip binary)"
ifeq ($(ENABLE_FIP),1)
@echo " Do not forget to set FIP deploydir folders (such as FIP_DEPLOYDIR_ROOT) to provide path to needed binaries"
endif
@echo
@echo "Available targets:"
@echo " all : build U-Boot binaries for defined config(s)"
@echo " clean : clean build directories from generated files"
version:
@if test ! -e .scmversion ; then echo $(UBOOT_LOCALVERSION) > $(SRC_PATH)/.scmversion; fi
all: uboot $(if $(ENABLE_FIP),fip)
uboot: version
@for config in $(UBOOT_CONFIGS); do \
uboot_config=$$(echo $$config | cut -d',' -f1) ; \
uboot_type=$$(echo $$config | cut -d',' -f2) ; \
uboot_binary=$$(echo $$config | cut -d',' -f3) ; \
uboot_suffix=$$(echo $$uboot_binary | cut -d'.' -f2) ; \
# Configure destination folder \
if [ "$$uboot_suffix" = "img" ]; then \
subfolder=/$$uboot_type ; \
else \
subfolder= ; \
fi ; \
mkdir -p $(DEPLOYDIR)$$subfolder ; \
mkdir -p $(DEPLOYDIR)$$subfolder/debug ; \
# Make sure about configuration set \
if test -z "$$uboot_config" -o -z "$$uboot_type" -o -z "$$uboot_binary"; then \
echo ; \
echo "[ERROR] UBOOT_CONFIGS wrongly configured. It should be space separated list of element <defconfig>,<type>,<binary>" ; \
echo ; \
exit 1 ; \
fi ; \
# Dynamic update for defconfig file \
if [ "$$uboot_suffix" = "stm32" ]; then \
if ! grep -q 'CONFIG_STM32MP15x_STM32IMAGE=y' "$(SRC_PATH)/configs/$$uboot_config"; then \
echo "CONFIG_STM32MP15x_STM32IMAGE=y" >> "$(SRC_PATH)/configs/$$uboot_config" ; \
fi ; \
fi ; \
# Init folder and defconfig selected \
if [ ! -d $(BLD_PATH)/$$uboot_type ]; then \
mkdir -p $(BLD_PATH)/$$uboot_type ; \
echo $(UBOOT_LOCALVERSION) > $(BLD_PATH)/$$uboot_type/.scmversion ; \
$(MAKE) -C $(SRC_PATH) O=$(BLD_PATH)/$$uboot_type $$uboot_config ; \
fi ; \
# Build binaries \
if [ -z "$(DEVICE_TREE)" ]; then \
$(MAKE) -C $(SRC_PATH) O=$(BLD_PATH)/$$uboot_type all ; \
# Copy binary files with explicit name \
cp -f $(BLD_PATH)/$$uboot_type/$$uboot_binary $(DEPLOYDIR)$$subfolder/u-boot-$$uboot_type.$$uboot_suffix ; \
if [ -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl.stm32 ]; then \
cp -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl.stm32 $(DEPLOYDIR)$$subfolder/u-boot-spl.stm32-$$uboot_type ; \
fi ; \
if [ -f $(BLD_PATH)/$$uboot_type/u-boot ]; then \
cp -f $(BLD_PATH)/$$uboot_type/u-boot $(DEPLOYDIR)$$subfolder/debug/u-boot-$$uboot_type.elf ; \
fi ; \
if [ -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl ]; then \
cp -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl $(DEPLOYDIR)$$subfolder/debug/u-boot-spl.elf-$$uboot_type ; \
fi ; \
# Install 'u-boot-nodtb.bin' binary in case '*.dtb' binary installation configured \
if [ "$$uboot_suffix" = "dtb" ]; then \
cp -f $(BLD_PATH)/$$uboot_type/u-boot-nodtb.bin $(DEPLOYDIR)$$subfolder/u-boot-nodtb.bin ; \
fi ; \
else \
for devicetree in $(DEVICE_TREE); do \
$(MAKE) -C $(SRC_PATH) O=$(BLD_PATH)/$$uboot_type all DEVICE_TREE=$$devicetree DEVICE_TREE_EXT=$$devicetree.dtb; \
# Copy binary files with explicit name \
cp -f $(BLD_PATH)/$$uboot_type/$$uboot_binary $(DEPLOYDIR)$$subfolder/u-boot-$$devicetree-$$uboot_type.$$uboot_suffix ; \
if [ -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl.stm32 ]; then \
cp -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl.stm32 $(DEPLOYDIR)$$subfolder/u-boot-spl.stm32-$$devicetree-$$uboot_type ; \
fi ; \
if [ -f $(BLD_PATH)/$$uboot_type/u-boot ]; then \
cp -f $(BLD_PATH)/$$uboot_type/u-boot $(DEPLOYDIR)$$subfolder/debug/u-boot-$$devicetree-$$uboot_type.elf ; \
fi ; \
if [ -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl ]; then \
cp -f $(BLD_PATH)/$$uboot_type/spl/u-boot-spl $(DEPLOYDIR)$$subfolder/debug/u-boot-spl.elf-$$devicetree-$$uboot_type ; \
fi ; \
# Install ''u-boot-nodtb.bin' binary in case '*.dtb' binary installation configured \
if [ "$$uboot_suffix" = "dtb" ]; then \
# Init soc suffix \
soc_suffix="" ; \
if [ -n "stm32mp15" ]; then \
for soc in stm32mp15; do \
if [ "$$(echo $$devicetree | grep -c $$soc)" -eq 1 ]; then \
soc_suffix="-$$soc" ; \
fi ; \
done ; \
fi ; \
cp -f $(BLD_PATH)/$$uboot_type/u-boot-nodtb.bin $(DEPLOYDIR)$$subfolder/u-boot-nodtb$$soc_suffix.bin ; \
fi ; \
done ; \
fi ; \
done
fip: uboot
FIP_DEPLOYDIR_UBOOT=$(DEPLOYDIR) FIP_DEVICETREE="$(DEVICE_TREE)" fiptool-stm32mp
clean:
@for config in $(UBOOT_CONFIGS); do \
uboot_type=$$(echo $$config | cut -d',' -f2) ; \
echo "Removing $(BLD_PATH)/$$uboot_type ..." ; \
rm -rf $(BLD_PATH)/$$uboot_type ; \
done
@echo "Removing $(DEPLOYDIR) ..."
@rm -rf $(DEPLOYDIR)
@echo