yocto-第40篇-beaglebone-yocto.conf配置分析之u-boot

By: fu linux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!

继续分析meta-yocto-bsp/conf/machine/beaglebone-yocto.conf配置文件的作用
Beagleboneblack在启动linux之前还有三个启动阶段:

引导
引导
引导
ROM code
MLO
u-boot
kernel

参考 Beagleboneblack的MLO文件干了些啥
这个博文里面也有些不当的地方:比如上电后执行的第一条指令就是从ROM code开始,相当于固化了一段启动代码到am335x芯片内部的ROM(Read only memory)中了,不是加载到RAM(DRAM)里面运行的,DRAM是外部的运存设备还没有被MLO初始化呢,MLO是在芯片内部的SRAM中运行的,SRAM的运行环境优势ROM code初始化的。要知道DRAM初始化好了才能加载u-boot和内核,要不然加载到DRAM中的u-boot和kernel中再去初始化DRAM会导致u-boot和kernel自身被破坏的,这个和Freescale的IMX平台启动类似,也是要先初始化RAM才能加载u-boot的哦。beaglebone没细看,但是大体是这个思路~

MLO(SPL)属于一个小型的u-boot, 也是由u-boot一起编译出来的

build] $ ls -l tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/image/boot
lrwxrwxrwx 1 peeta peeta     31 1月  10 02:51 MLO -> MLO-beaglebone-yocto-2020.01-r0
-rw-r--r-- 1 peeta peeta 107784 1月  10 02:51 MLO-beaglebone-yocto-2020.01-r0
-rw-r--r-- 1 peeta peeta 764440 1月  10 02:51 u-boot-beaglebone-yocto-2020.01-r0.img
lrwxrwxrwx 1 peeta peeta     38 1月  10 02:51 u-boot.img -> u-boot-beaglebone-yocto-2020.01-r0.img
  • 1
  • 2
  • 3
  • 4
  • 5

因此先看u-boot.

u-boot相关

在配置文件中有这么一个声明:

EXTRA_IMAGEDEPENDS += "u-boot"
  • 1

和u-boot相关的配置还有:

SERIAL_CONSOLES ?= "115200;ttyS0 115200;ttyO0 115200;ttyAMA0"
SERIAL_CONSOLES_CHECK = "${SERIAL_CONSOLES}"
SPL_BINARY = "MLO"
UBOOT_SUFFIX = "img"
UBOOT_MACHINE = "am335x_evm_defconfig"
UBOOT_ENTRYPOINT = "0x80008000"
UBOOT_LOADADDRESS = "0x80008000"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

SERIAL_CONSOLES变量

指定串口波特率和节点名

EXTRA_IMAGEDEPENDS 变量

首先看这个变量,这个变量用于某些recipes(通常就是某些机器的bootloader程序)不用安装到rootfs根文件系统当中去,但构建images(像core-image-minimal目标)时又依赖于这个recipe时用到。
我们知道u-boot是在kernel和文件系统等之前启动的,负责引导系统linux kernel启动的,所以它不用安装到文件系统中。beaglebone内核启动需要又u-boot来引导,所以这里images是需要依赖u-boot编译成功的。

知识点:需要将软件包添加到rootfs根文件系统中的话,可以使用 RDEPENDS和 RRECOMMENDS相关的变量声明。u-boot不是哈。

u-boot对应的recipe文件是:

$ cat meta/recipes-bsp/u-boot/u-boot_2020.01.bb
require u-boot-common.inc
require u-boot.inc

DEPENDS += "bc-native dtc-native"
  • 1
  • 2
  • 3
  • 4
  • 5

看文件内容,它实际引用了u-boot-common.inc和u-boot.inc两个头文件,

u-boot-common.inc

这个文件定义了u-boot的SRCREV和SRC_URI两个变量,后者就是u-boot的下载地址和补丁文件。

cat meta/recipes-bsp/u-boot/u-boot-common.inc
SRC_URI = "git://git.denx.de/u-boot.git \
           file://remove-redundant-yyloc-global.patch \
          " 
  • 1
  • 2
  • 3
  • 4

同时还定义了

S = "${WORKDIR}/git"
B = "${WORKDIR}/build"
do_configure[cleandirs] = "${B}"
  • 1
  • 2
  • 3

查看:

build]$ bitbake -e u-boot | grep ^S=   
S="/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/git"
  • 1
  • 2

u-boot.inc

看文件meta/recipes-bsp/u-boot/u-boot.inc

PACKAGE_ARCH = "${MACHINE_ARCH}" #对应beaglebone_yocto
DEPENDS += "kern-tools-native" #依赖于这个工具包
inherit uboot-config uboot-extlinux-config uboot-sign deploy cml1 python3native #继承这些类,可到meta/classes文件中去看相应的bbclass文件内容。
  • 1
  • 2
  • 3

下面这些

EXTRA_OEMAKE = 'CROSS_COMPILE=${TARGET_PREFIX} CC="${TARGET_PREFIX}gcc ${TOOLCHAIN_OPTIONS}" V=1'
EXTRA_OEMAKE += 'HOSTCC="${BUILD_CC} ${BUILD_CFLAGS} ${BUILD_LDFLAGS}"'
EXTRA_OEMAKE += 'STAGING_INCDIR=${STAGING_INCDIR_NATIVE} STAGING_LIBDIR=${STAGING_LIBDIR_NATIVE}'
  • 1
  • 2
  • 3
bitbake -e u-boot | grep -i ^TARGET_PREFIX=
TARGET_PREFIX="arm-poky-linux-gnueabi-"
  • 1
  • 2

因此对应的CC就是:

export CC="arm-poky-linux-gnueabi-gcc  -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a8 -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot"
  • 1

有点类似于在u-boot的Makefile文件中修改交叉编译:

# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
#add by fulinux
CROSS_COMPILE=arm-poky-linux-gnueabi- #这里
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当然也可以在执行make的时候手动指定CROSS_COMPILE等参数。

其他的:

HOSTCC="gcc  -isystem/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/include -O2 -pipe -L/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib                         -L/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/lib                         -Wl,--enable-new-dtags                         -Wl,-rpath-link,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib                         -Wl,-rpath-link,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/lib                         -Wl,-rpath,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib                         -Wl,-rpath,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/lib                         -Wl,-O1 -Wl,--allow-shlib-undefined -Wl,--dynamic-linker=/home/peeta/beaglebone/build/tmp/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2"
STAGING_INCDIR="/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot/usr/include"
  • 1
  • 2

最终make的参数是这样:

make CROSS_COMPILE=arm-poky-linux-gnueabi- CC="arm-poky-linux-gnueabi-gcc  --sysroot=/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot" V=1 HOSTCC="gcc  -isystem/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/include -O2 -pipe -L/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib                         -L/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/lib                         -Wl,--enable-new-dtags                         -Wl,-rpath-link,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib                         -Wl,-rpath-link,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/lib                         -Wl,-rpath,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib                         -Wl,-rpath,/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/lib                         -Wl,-O1 -Wl,--allow-shlib-undefined -Wl,--dynamic-linker=/home/peeta/beaglebone/build/tmp/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2" STAGING_INCDIR=/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/include STAGING_LIBDIR=/home/peeta/beaglebone/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/recipe-sysroot-native/usr/lib "$@" #$@是目标文件的意思
  • 1

再看文件meta/recipes-bsp/u-boot/u-boot.inc

PACKAGECONFIG ??= "openssl" #不清楚这里的u-boot有没有使用这个功能,这个一般适用于网络通信加密
PACKAGECONFIG[openssl] = ",,openssl-native"
  • 1
  • 2

先忽略

??=或者?=赋值什么意思

有些表达式中有??=或者?=赋值语句,表示弱赋值。比如:

ABC ??= "123"
  • 1

如果没有其他地方对变量ABC重新赋值,那么ABC默认就是123。

如果在其他地方有这样的定义:

ABC ?= "456"
  • 1

那么最终变量ABC的值是456

如果后面又有这样的赋值

ABC = "678"
  • 1

那么最终变量ABC的值是678。

话说如果同时出现了:

ABC ?= "456"
...
ABC ?= "123"
  • 1
  • 2
  • 3

那么此时ABC是什么呢?答案是456,因为在解析第一个ABC时没有发现被赋值,因此给它赋值为456, 再解析下面一个ABC变量时发现已经有值了就不会继续赋值。

继续u-boot.inc文件内容:

UBOOT_SUFFIX ??= "bin" #在beaglebone-yocto.conf配置文件中已经将其定义为了img后缀。
UBOOT_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.${UBOOT_SUFFIX}" #对应u-boot-beaglebone-yocto-2020.01-r0.img,PV是u-boot的版本2020.01,PR是r0(通常就是这个)
UBOOT_SYMLINK ?= "u-boot-${MACHINE}.${UBOOT_SUFFIX}" #镜像的符号链接u-boot.img --> u-boot-beaglebone-yocto-2020.01-r0.img
UBOOT_MAKE_TARGET ?= "all"  #编译所有目标,参看makefile里面
  • 1
  • 2
  • 3
  • 4

上面主要是定义u-boot镜像文件名,还有符号链接文件名,以及编译的目标。

下面这个是设置SPL,看下面注释内容,就知道有些u-boot版本是会编译SPL的。

# Some versions of u-boot build an SPL (Second Program Loader) image that
# should be packaged along with the u-boot binary as well as placed in the 
# deploy directory.  For those versions they can set the following variables
# to allow packaging the SPL.
SPL_BINARY ?= ""
SPL_BINARYNAME ?= "${@os.path.basename(d.getVar("SPL_BINARY"))}"
SPL_IMAGE ?= "${SPL_BINARYNAME}-${MACHINE}-${PV}-${PR}"  #对应MLO-beaglebone-yocto-2020.01-r0
SPL_SYMLINK ?= "${SPL_BINARYNAME}-${MACHINE}" #对应MLO-beaglebone-yocto
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

SPL_BINARY变量在conf文件中有赋值为MLO。

UBOOT环境变量

u-boot通常也有环境变量,也就是启动参数什么的,比如:

bootargs console=${console} ${optargs} root=PARTUUID=${uuid} rw
  • 1

u-boot环境变量是保存在flash上的,有的u-boot环境变量通常是写在一个平台的头文件中的。这里好像是保存到一个文件上的:

cat tmp/deploy/images/beaglebone-yocto/u-boot-initial-env
bootcmd=if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run
loadaddr=0x82000000
mmcdev=0
... #还有很多
  • 1
  • 2
  • 3
  • 4
  • 5

这个保存环境变量和启动参数的文件名也有规定:

# Additional environment variables or a script can be installed alongside
# u-boot to be used automatically on boot.  This file, typically 'uEnv.txt'
# or 'boot.scr', should be packaged along with u-boot as well as placed in the 
# deploy directory.  Machine configurations needing one of these files should
# include it in the SRC_URI and set the UBOOT_ENV parameter.
UBOOT_ENV_SUFFIX ?= "txt"
UBOOT_ENV ?= ""
UBOOT_ENV_BINARY ?= "${UBOOT_ENV}.${UBOOT_ENV_SUFFIX}"
UBOOT_ENV_IMAGE ?= "${UBOOT_ENV}-${MACHINE}-${PV}-${PR}.${UBOOT_ENV_SUFFIX}"
UBOOT_ENV_SYMLINK ?= "${UBOOT_ENV}-${MACHINE}.${UBOOT_ENV_SUFFIX}"
上面这几个变量没看到使用
# Default name of u-boot initial env, but enable individual recipes to change
# this value.
UBOOT_INITIAL_ENV ?= "${PN}-initial-env" #对应:u-boot-initial-env
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

看注释是说环境变量是在u-boot旁边,猜测下:

  1. env拼接在u-boot.img旁边,整合成一个镜像~;
  2. env文本文件放置在一个指定起点地址的的flash中,有u-boot读取;
  3. 将env文件放置在某个文件系统分区中,比如vfat、ext分区中,u-boot是支持这个文件系统的哦;

看下deploy目录下的文件:

build]$ ls -l tmp/deploy/images/beaglebone-yocto/u-boot-initial-env*
lrwxrwxrwx 2 peeta peeta   46 1月  10 02:51 tmp/deploy/images/beaglebone-yocto/u-boot-initial-env -> u-boot-initial-env-beaglebone-yocto-2020.01-r0
lrwxrwxrwx 2 peeta peeta   46 1月  10 02:51 tmp/deploy/images/beaglebone-yocto/u-boot-initial-env-beaglebone-yocto -> u-boot-initial-env-beaglebone-yocto-2020.01-r0
-rw-r--r-- 2 peeta peeta 9615 1月  10 02:51 tmp/deploy/images/beaglebone-yocto/u-boot-initial-env-beaglebone-yocto-2020.01-r0
  • 1
  • 2
  • 3
  • 4

u-boot.in后续定义了如下函数:

do_configure () {
	...
	oe_runmake -C ${S} O=${B}/${config} ${config}
}
do_compile () {
	...
	oe_runmake -C ${S} O=${B}/${config} ${UBOOT_MAKE_TARGET}
	...
	cp ${B}/${config}/${binary} ${B}/${config}/u-boot-${type}.${UBOOT_SUFFIX}
	...
	oe_runmake -C ${S} O=${B}/${config} u-boot-initial-env
	cp ${B}/${config}/u-boot-initial-env ${B}/${config}/u-boot-initial-env-${type}
}
do_install () {
	if (...)
	install -D -m 644 ${B}/${config}/u-boot-${type}.${UBOOT_SUFFIX} ${D}/boot/u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX}
	...
	ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${D}/boot/${UBOOT_BINARY}-${type}
	...
	install -D -m 644 ${B}/u-boot-initial-env ${D}/${sysconfdir}/${UBOOT_INITIAL_ENV}-${MACHINE}-${PV}-${PR}
	...
}
do_deploy () {
	...
	install -D -m 644 ${B}/${config}/u-boot-${type}.${UBOOT_SUFFIX} ${DEPLOYDIR}/u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX}
	...
	cd ${DEPLOYDIR}
	ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${UBOOT_SYMLINK}-${type}
	...
	install -D -m 644 ${B}/${config}/u-boot-initial-env-${type} ${DEPLOYDIR}/${UBOOT_INITIAL_ENV}-${MACHINE}-${type}-${PV}-${PR}
	...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

其中oe_runmake相当于make命令,install安装的命令,有点相当于cp命令。

最后规定了任务的顺序, do_deploy在do_compile之后:

addtask deploy before do_build after do_compile
  • 1

默认情况下,do_deploy任务不作为默认的任务添加,因此需要手动添加。如果希望任务在do_compile之后运行,可以通过上面的方式添加它,也可以去掉before do_build,因此可以是如下这样:

addtask deploy after do_compile
  • 1

通过下面的命令查看:

build]$ bitbake u-boot -c listtasks
do_build                              Default task for a recipe - depends on all other normal tasks required to 'build' a recipe
do_checkuri                           Validates the SRC_URI value
do_clean                              Removes all output files for a target
do_cleanall                           Removes all output files, shared state cache, and downloaded source files for a target
do_cleansstate                        Removes all output files and shared state cache for a target
do_compile                            Compiles the source in the compilation directory
do_configure                          Configures the source by enabling and disabling any build-time and configuration options for the software being built
do_create_extlinux_config             
do_deploy                             Writes deployable output files to the deploy directory
do_deploy_setscene                    Writes deployable output files to the deploy directory (setscene version)
do_deploy_source_date_epoch           
do_deploy_source_date_epoch_setscene   (setscene version)
do_devpyshell                         Starts an interactive Python shell for development/debugging
do_devshell                           Starts a shell with the environment set up for development/debugging
do_diffconfig                         Compares the old and new config files after running do_menuconfig for the kernel
do_fetch                              Fetches the source code
do_install                            Copies files from the compilation directory to a holding area
do_listtasks                          Lists all defined tasks for a target
do_menuconfig                         Runs 'make menuconfig' for the kernel
do_package                            Analyzes the content of the holding area and splits it into subsets based on available packages and files
do_package_qa                         Runs QA checks on packaged files
do_package_qa_setscene                Runs QA checks on packaged files (setscene version)
do_package_setscene                   Analyzes the content of the holding area and splits it into subsets based on available packages and files (setscene version)
do_package_write_rpm                  Creates the actual RPM packages and places them in the Package Feed area
do_package_write_rpm_setscene         Creates the actual RPM packages and places them in the Package Feed area (setscene version)
do_packagedata                        Creates package metadata used by the build system to generate the final packages
do_packagedata_setscene               Creates package metadata used by the build system to generate the final packages (setscene version)
do_patch                              Locates patch files and applies them to the source code
do_populate_lic                       Writes license information for the recipe that is collected later when the image is constructed
do_populate_lic_setscene              Writes license information for the recipe that is collected later when the image is constructed (setscene version)
do_populate_sysroot                   Copies a subset of files installed by do_install into the sysroot in order to make them available to other recipes
do_populate_sysroot_setscene          Copies a subset of files installed by do_install into the sysroot in order to make them available to other recipes (setscene version)
do_prepare_recipe_sysroot             
do_unpack                             Unpacks the source code into a working directory
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

UBOOT_SUFFIX

指定生成u-boot镜像的后缀名,这里就是:

u-boot.img
  • 1

UBOOT_MACHINE变量

UBOOT_MACHINE定义了配置文件,对应的u-boot配置文件是:

build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/1_2020.01-r0/git/configs/am335x_evm_defconfig
  • 1

UBOOT_ENTRYPOINT

指定u-boot镜像的入口地址。

UBOOT_ENTRYPOINT = "0x80008000"
  • 1

看完帮忙点个赞~