Rockchip RK3399 - TPL/SPL方式加载uboot

----------------------------------------------------------------------------------------------------------------------------开发板  :NanoPC-T4开发板eMMC   :16GBLPDDR3:4GB显示屏  :15.6英寸HDMI接口显示屏u-boot    :2017.09----------------------------------------------------------------------------------------------------------------------------

NanoPC-T4开发板,主控芯片是Rockchip RK3399,big.LITTLE大小核架构,双Cortex-A72大核(up to 2.0GHz) + 四Cortex-A53小核结构(up to 1.5GHz);Cortex-A72处理器是Armv8-A架构下的一款高性能、低功耗的处理器。

我们接着上一节,介绍Rockchip处理器启动支持的两种引导方式:

  • TPL/SPL加载:使用Rockchip官方提供的TPL/SPL U-boot(就是我们上面说的小的uboot),该方式完全开源;
  • 官方固件加载:使用Rockchip idbLoader,来自Rockchip rkbin项目的Rockchip DDR初始化bin和miniloader bin,该方式不开源;

这一节我们将介绍采用TPL/SPL方式,如何编译源码以及烧录程序到eMMC,从而完成uboot的启动。

一、uboot

uboot通常有三种:

  • uboot官方源码:https://github.com/u-boot/u-boot,uboot官方源码是由uboot官方维护,支持非常全面的芯片,但对具体某款开发板支持情况一般;
  • 半导体厂商瑞芯微官方源码:https://github.com/rockchip-linux/u-boot,半导体厂商基于uboot官方源码进行修改,对自家的芯片进行完善的支持,针对某款处理器支持情况较好;
  • 开发板友善之家官方源码:https://github.com/friendlyarm/uboot-rockchip,开发板厂商基于半导体厂商维护的uboot,对自家的开发板进行板级支持,针对某款开发板支持情况较好;

我们不要上来就去移植uboot官方的源码,一般来说uboot官方的代码不做任何改动,是无法在我们板子上直接运行的。我们先去把Rockchip官方提供的207.09版本的uboot代码下载下来,编译之后看看能不能运行,如果可以的话,再去参考Rockchip官方的uboot去移植最新版本的uboot。

这里有一点需要补充的是:Rockchip官方提供的uboot 207.09版本做了大量的改动,尤其是引导内核启动上,为了支持多种内核镜像加载方式,对uboot源码进行了大量修改,所以要求我们烧录的内核镜像也要按照官方指定的格式调整否则无法被uboot正确引导。

1.1 下载源码

我们可以在Rockchip的github上下载到芯片厂商提供的u-boot源码,如下图所示:

Rockchip RK3399 - TPL/SPL方式加载uboot_第1张图片

这里我们下载的是最新的next-dev分支的代码:

root@zhengyang:/work/sambashare/rk3399# git clone https://github.com/rockchip-linux/u-boot.git --depth 1 -b next-dev

这里我是下载到/work/sambashare/rk3399路径下的,这个路径后面专门存放与rk3399相关的内容。

进入到u-boot文件夹里,这就是我们需要的uboot的源码了,后面就可以进行二次开发了;

root@zhengyang:/work/sambashare/rk3399/u-boot# cd ..
root@zhengyang:/work/sambashare/rk3399# cd u-boot/
root@zhengyang:/work/sambashare/rk3399/u-boot# ls -l
总用量 488
drwxr-xr-x   2 root root   4096 5月   7 20:00 api
drwxr-xr-x  14 root root   4096 5月   7 20:00 arch
drwxr-xr-x 181 root root   4096 5月   7 20:00 board
drwxr-xr-x   6 root root   4096 5月   7 20:00 cmd
drwxr-xr-x   5 root root   4096 5月   7 20:00 common
-rw-r--r--   1 root root   2260 5月   7 20:00 config.mk
drwxr-xr-x   2 root root  69632 5月   7 20:00 configs
drwxr-xr-x   2 root root   4096 5月   7 20:00 disk
drwxr-xr-x  10 root root  12288 5月   7 20:00 doc
drwxr-xr-x   3 root root   4096 5月   7 20:00 Documentation
drwxr-xr-x  56 root root   4096 5月   7 20:00 drivers
drwxr-xr-x   2 root root   4096 5月   7 20:00 dts
drwxr-xr-x   2 root root   4096 5月   7 20:00 env
drwxr-xr-x   4 root root   4096 5月   7 20:00 examples
drwxr-xr-x  12 root root   4096 5月   7 20:00 fs
drwxr-xr-x  32 root root  16384 5月   7 20:00 include
-rw-r--r--   1 root root   1863 5月   7 20:00 Kbuild
-rw-r--r--   1 root root  14162 5月   7 20:00 Kconfig
drwxr-xr-x  14 root root   4096 5月   7 20:00 lib
drwxr-xr-x   2 root root   4096 5月   7 20:00 Licenses
-rw-r--r--   1 root root  12587 5月   7 20:00 MAINTAINERS
-rw-r--r--   1 root root  56469 5月   7 20:00 Makefile
-rwxr-xr-x   1 root root  19845 5月   7 20:00 make.sh
drwxr-xr-x   2 root root   4096 5月   7 20:00 net
-rwxr-xr-x   1 root root   1640 5月   7 20:00 pack_resource.sh
drwxr-xr-x   5 root root   4096 5月   7 20:00 post
-rw-r--r--   1 root root     34 5月   7 20:00 PREUPLOAD.cfg
-rw-r--r--   1 root root 189024 5月   7 20:00 README
drwxr-xr-x   6 root root   4096 5月   7 20:00 scripts
-rw-r--r--   1 root root     17 5月   7 20:00 snapshot.commit
drwxr-xr-x  12 root root   4096 5月   7 20:00 test
drwxr-xr-x  16 root root   4096 5月   7 20:00 tools
View Code

需要注意的是:尽量不要下载release分支,最初我也下载了这个分支,这里分支默认配置有问题。其中配置项:CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000,表示SPL为ATF预留了0x50000大小的内存空间,这个地址范围是从0x00000008开始的,而0x500008之后是SPL代码。程序运行后,SPL从eMMC加载0x00040000.bin到内存地址0x40000时,由于文件也比较大,直接覆盖了原有的SPL代码,导致程序直接卡死。

1.2 配置uboot

uboot的编译分为两步:配置、编译。单板的默认配置在configs目录下,这里我们直接选择configs/evb-rk3399_defconfig,这是Rockchip评估板的配置:

CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_ROCKCHIP_RK3399=y
CONFIG_RKIMG_BOOTLOADER=y
# CONFIG_USING_KERNEL_DTB is not set
CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
CONFIG_DEBUG_UART=y
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.py"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_ANDROID_BOOTLOADER=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
CONFIG_SPL_ATF=y
CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
CONFIG_FASTBOOT_BUF_ADDR=0x00800800
CONFIG_FASTBOOT_BUF_SIZE=0x04000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
CONFIG_CMD_LOAD_ANDROID=y
CONFIG_CMD_BOOT_ANDROID=y
CONFIG_CMD_BOOT_ROCKCHIP=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_RKPARM_PARTITION=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_LIVE=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
CONFIG_SPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
CONFIG_ROCKCHIP_EFUSE=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
CONFIG_SPL_RAM=y
CONFIG_ROCKCHIP_SDRAM_COMMON=y
CONFIG_DM_RESET=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207
CONFIG_USB_GADGET_PRODUCT_NUM=0x330a
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_MCS7830=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_DRM_ROCKCHIP=y
CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y
CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y
CONFIG_LCD=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_SPL_TINY_MEMSET=y
CONFIG_ERRNO_STR=y
View Code

因此执行如下命令,生成.config文件:

root@zhengyang:/work/sambashare/rk3399/u-boot# make evb-rk3399_defconfig V=1

输出如下(忽略编译器警告信息):

root@zhengyang:/work/sambashare/rk3399/u-boot#  make evb-rk3399_defconfig V=1
make -f ./scripts/Makefile.build obj=scripts/basic
  cc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer      -o scripts/basic/fixdep scripts/basic/fixdep.c
rm -f .tmp_quiet_recordmcount
make -f ./scripts/Makefile.build obj=scripts/kconfig evb-rk3399_defconfig
  cc -Wp,-MD,scripts/kconfig/.conf.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer    -D_GNU_SOURCE -I/usr/include/ncursesw -DCURSES_LOC="" -DNCURSES_WIDECHAR=1 -DLOCALE   -c -o scripts/kconfig/conf.o scripts/kconfig/conf.c
  cat scripts/kconfig/zconf.tab.c_shipped > scripts/kconfig/zconf.tab.c
  cat scripts/kconfig/zconf.lex.c_shipped > scripts/kconfig/zconf.lex.c
  cat scripts/kconfig/zconf.hash.c_shipped > scripts/kconfig/zconf.hash.c
  cc -Wp,-MD,scripts/kconfig/.zconf.tab.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer    -D_GNU_SOURCE -I/usr/include/ncursesw -DCURSES_LOC="" -DNCURSES_WIDECHAR=1 -DLOCALE  -Iscripts/kconfig -c -o scripts/kconfig/zconf.tab.o scripts/kconfig/zconf.tab.c
  cc  -o scripts/kconfig/conf scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o
scripts/kconfig/conf  --defconfig=arch/../configs/evb-rk3399_defconfig Kconfig
#
# configuration written to .config
#

配置主要分为三个步骤:

  • 第一步:执行make -f ./scripts/Makefile.build obj=scripts/basic,编译生成scripts/basic/fixdep工具;
  • 第二步:执行make -f ./scripts/Makefile.build obj=scripts/kconfig evb-rk3399_defconfig,编译生成scripts/kcofig/conf工具;
  • 第三步:执行scripts/kconfig/conf --defconfig=arch/../configs/evb-rk3399_defconfig Kconfig,scripts/kconfig/conf根据evb-rk3399_defconfig生成.config配置文件;

这里会在当前路径下生成.config文件,这实际上是一个配置文件,这个文件是怎么生成的呢,实际上就是根据configs/evb-rk3399_defconfig文件以及我们make menuconfig看到的那些默认配置(或者说是各个目录下的Kconfig文件中有效的default项)生成的。

在进行make编译的时候,会根据这个文件生成include/config/auto.conf文件,同时在顶层Makefile会引入auto.conf文件:

ifeq ($(dot-config),1)
# Read in config
-include include/config/auto.conf

这样在执行make编译过程中,就可以根据include/config/auto.conf中的宏的定义编译不同的库文件。

1.2.1 配置串口波特率

uboot中默认的调试串口波特率是1500000,有很多的调试终端不支持1.5M的波特率,我们可以把波特率重新配置下,再u-boot文件夹下输入命令:make menuconfig配置;

Device Drivers  ---> 
      Serial drivers  --->     
           (150000) Default baudrate  

注意: 波特率数值如果无法删除,按CTRL+回车键尝试。

也可以直接编辑.config配置项:

CONFIG_BAUDRATE=1500000
1.2.2 配置uboot启动倒计时

如果在uboot启动倒计时结束之前,没有按下任何键,将会执行那么将执行也就是bootcmd中配置中的命令,bootcmd中保存着默认的启动命令。

(5) delay in seconds before automatically booting

也可以直接编辑.config配置项:

CONFIG_BOOTDELAY=5

保存文件,输入文件名为evb-rk3399_defconfig ,在当前路径下生成evb-rk3399_defconfig :存档:

root@zhengyang:/work/sambashare/rk3399/u-boot# mv evb-rk3399_defconfig ./configs/

注意:如果需要配置生效,需要使用make distclean清除之前的配置,重新执行配置命令。

更多内容可以参考我之前写的有关s3c2440 uboot配置的文章:make smdk2410_defconfig配置分析,虽然SoC不同,但是make配置流程是一样的。

1.2.3 开启调试信息

在uboot启动时,如果我们想打印更加详细的信息,可以在include/configs/evb_rk3399.h中加入如下宏:

#define DEBUG

后面测试发现,设置了这个虽然可以输出一些调试信息,但是确无法进入uboot命令行,因此这个非特殊场景,尽量不要设置。

1.3 编译uboot

执行make命令,生成u-boot文件:

root@zhengyang:/work/sambashare/rk3399/u-boot# make ARCH=arm CROSS_COMPILE=arm-linux- 

编译过程我们会发现有一些错误,这些错误的处理我们在文章的最后单独介绍。

更多内容可以参考我之前写的有关s3c2440 uboot编译的文章:make编译正向分析之顶层目标依赖,虽然SoC不同,但是make编译流程是一样的。

1.4 image镜像

成功编译之后,就会在 uboot源码的根目录下产生多个可执行二进制文件以及编译过程文件,这些文件都是 u-bootxxx 的命名方式。这些文件由一些列名为.xxx.cmd 的文件生成,.xxx.cmd 这些文件都是由编译系统产生的用于处理最终的可执行程序的。

在uboot根录下生成文件有:

root@zhengyang:/work/sambashare/rk3399/u-boot# ll u-boot*   Sys*
-rw-r--r-- 1 root root  153740 5月  14 10:30 System.map
-rwxr-xr-x 1 root root 6872736 5月  14 10:30 u-boot*
-rw-r--r-- 1 root root  931504 5月  14 10:30 u-boot.bin
-rw-r--r-- 1 root root   15808 5月  14 10:30 u-boot.cfg
-rw-r--r-- 1 root root    9996 5月  14 10:30 u-boot.cfg.configs
-rw-r--r-- 1 root root   51685 5月  14 10:30 u-boot.dtb       # 设备树
-rw-r--r-- 1 root root  931501 5月  14 10:30 u-boot-dtb.bin   # 等同u-boot.bin
-rw-r--r-- 1 root root  932864 5月  14 10:30 u-boot-dtb.img   # 等同u-boot.img
-rw-r--r-- 1 root root  932864 5月  14 10:30 u-boot.img
-rw-r--r-- 1 root root    1304 5月  14 10:30 u-boot.lds
-rw-r--r-- 1 root root  800454 5月  14 10:30 u-boot.map
-rwxr-xr-x 1 root root  879816 5月  14 10:30 u-boot-nodtb.bin*
-rwxr-xr-x 1 root root 2529568 5月  14 10:30 u-boot.srec*
-rw-r--r-- 1 root root  300850 5月  14 10:30 u-boot.sym

其中:

  • u-boot: 这个文件是编译后产生的ELF格式的最原始的uboot镜像文件,后续的文件都是由它产生的.u-boot.cmd 这个命令脚本描述了如何产生;
  • u-boot-nodtb.bin: 这文件是使用编译工具链的objcopy工具从u-boot这个文件中提取来的,它只包含可执行的二进制代码。就是把 u-boot这个文件中对于执行不需要的节区删除后剩余的仅执行需要的部分。由 .u-boot-nodtb.bin.cmd 这个命令脚本产生;
  • u-boot-dtb.bin: 在u-boot-nodtb.bin尾部拼接上设备树后形成的文件。由.u-boot-dtb.bin.cmd这个命令脚本产生;
  • u-boot.bin: 就是把u-boot-dtb.bin重命名得到的。由.u-boot.bin.cmd这个命令脚本产生;
  • u-boot.img: 在u-boot.bin开头拼接一些信息后形成的文件。由 .u-boot.img.cmd这个命令脚本产生;
  • u-boot-dtb.img: 在 u-boot.bin开头拼接一些信息后形成的文件。由 .u-boot-dtb.img.cmd这个命令脚本产生;
  • u-boot.srec: S-Record 格式的镜像文件。由.u-boot.srec.cmd这个命令脚本产生;
  • u-boot.sym: 这个是从u-boot中导出的符号表文件。由.u-boot.sym.cmd这个命令脚本产生;
  • u-boot.lds: 编译使用的链接脚本文件。由 .u-boot.lds.cmd 个命令脚本产生;
  • u-boot.map: 编译的内存映射文件。该文件是有编译工具链的连接器输出的;
  • System.map: 记录u-boot中各个符号在内核中位置,但是这个文件是使用了nm和grep工具来手动生成的;

由于开启了SPL和TPL 的,因此,在编译uboot时会额外单独编译SPL、TPL,编译产生的镜像文件就存放在 ./spl、./tpl目录下。这下面的镜像生成方式与uboot基本是一模一样的。

root@zhengyang:/work/sambashare/rk3399/u-boot# ls tpl
arch   cmd     drivers  env  include  u-boot.cfg      u-boot-tpl      u-boot-tpl.dtb      u-boot-tpl.map        u-boot-tpl.sym
board  common  dts      fs   lib      u-boot-spl.lds  u-boot-tpl.bin  u-boot-tpl-dtb.bin  u-boot-tpl-nodtb.bin
root@zhengyang:/work/sambashare/rk3399/u-boot# ls spl
arch   cmd     drivers  env  include  u-boot.cfg  u-boot-spl.bin  u-boot-spl-dtb.bin  u-boot-spl.map        u-boot-spl.sym
board  common  dts      fs   lib      u-boot-spl  u-boot-spl.dtb  u-boot-spl.lds      u-boot-spl-nodtb.bin

以SPL为例:

  • u-boot-spl: 这个文件是编译后产生的 ELF格式的SPL镜像文件,后续的文件都是由它产生的.u-boot-spl.cmd 这个命令脚本描述了如何产生;
  • u-boot-spl-nodtb.bin: 这文件是使用编译工具链的objcopy工具从u-boot-spl这个文件中提取来的,它只包含可执行的二进制代码。就是把 u-boot-spl 这个文件中对于执行不需要的节区删除后剩余的仅执行需要的部分。由 .u-boot-spl-nodtb.bin.cmd 这个命令脚本产生;
  • u-boot-spl-dtb.bin: 在 u-boot-nodtb.bin 尾部依次拼接上 u-boot-spl-pad.bin 和 u-boot-spl.dtb 后形成的文件。由 .u-boot-spl-dtb.bin.cmd 这个命令脚本产生;
  • u-boot-spl.bin: 就是把 u-boot-dtb.bin 重命名得到的。由 .u-boot-spl.bin.cmd 这个命令脚本产生;
  • u-boot-spl.lds: 编译使用的链接脚本文件。由 .u-boot-spl.lds.cmd 这个命令脚本产生;
  • u-boot-spl.map: 编译SPL的内存映射文件;
  • u-boot-spl.dtb: 这个是编译好的设备树二进制文件。就是 ./dts/dt.dtb 重命名得到的。./dts/dt.dtb 来自于 arch/arm/dts/stm32f769-eval.dtb 重命名;

二、idbloader.img

我们基于uboot源码编译出TPL/SPL,其中TPL负责实现DDR初始化,TPL初始化结束之后会回跳到BootROM程序,BootROM程序继续加载SPL,SPL加载u-boot.itb文件,然后跳转到uboor执行。

idbloader.img是由tpl/u-boot-tpl.bin和spl/u-boot-spl.bin文件生成,这里我们需要使用到tools目录下的mkimage工具。

2.1 tpl/u-boot-tpl.bin

在u-boot目录下执行:

root@zhengyang:/work/sambashare/rk3399/u-boot# tools/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin idbloader.img
Image Type:   Rockchip RK33 (SD/MMC) boot image
Init Data Size: 81920 bytes

其中:

  • -n rk3399将镜像文件的名称设置为"rk3399";
  • -T rksd将映像类型指定为Rockchip SD卡启动映像;
  • -d  tpl/u-boot-tpl.bin将生成的TPL镜像文件"tpl/u-boot-tpl.bin"指定为输入文件,而idbloader.img则指定为输出文件。

生成idbloader.img文件:

root@zhengyang:/work/sambashare/rk3399/u-boot# ll idbloader.img
-rw-r--r-- 1 root root 83968 5月  14 10:38 idbloader.img

2.2 spl/u-boot-spl.bin

将spl/u-boot-spl.bin合并到idbloader.img:

root@zhengyang:/work/sambashare/rk3399/u-boot# cat spl/u-boot-spl.bin >> idbloader.img
root@zhengyang:/work/sambashare/rk3399/u-boot# ll idbloader.img
-rw-r--r-- 1 root root 210675 5月  14 10:39 idbloader.img

三、u-boot.idb

u-boot.itb实际上是u-boot.img的另一个变种,也是通过mkimage构建出来的,依赖于u-boot.its u-boot.dtb u-boot-nodtb.bin这三个文件。在顶层Makefile文件中:

u-boot.itb: u-boot-nodtb.bin dts/dt.dtb $(U_BOOT_ITS) FORCE
        $(call if_changed,mkfitimage)

这里的mkfitimage被设置为了:

cmd_mkfitimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -f $(U_BOOT_ITS) -E $@ \
        $(if $(KBUILD_VERBOSE:1=), >$(MKIMAGEOUTPUT))

3.1 FIT介绍

FIT是flattened image tree的简称,它采用了device tree source filse(DTS)的语法,生成的image文件也和dtb文件类似(称做itb)。

注意:这一小节只是补充关于FIT的相关知识,并不是编译u-boot.itb的步骤。

3.1.1 生成步骤

其中image source file(.its)和device tree source file(.dts)类似,负责描述要生成的image file的信息。mkimage和dtc工具,可以将.its文件以及对应的image data file,打包成一个image file。

3.1.2 image source file语法

image source file的语法和device tree source file完全一样,只不过自定义了一些特有的节点,包括images、configurations等。说明如下:

(1) images节点

指定所要包含的二进制文件,可以指定多种类型的多个文件,例如u-boot.its中的包含了1个standalone image、5个firmware image、1个fdt image。每个文件都是images下的一个子node,例如:

atf@1 {
        description = "ARM Trusted Firmware";
        data = /incbin/("bl31_0x00040000.bin");
        type = "firmware";
        arch = "arm64";
        os = "arm-trusted-firmware";
        compression = "none";
        load = <0x00040000>;
        entry = <0x00040000>;
};

可以包含如下的关键字:

  • description:描述,可以随便写;
  • data:二进制文件的路径,格式为/incbin/("path/to/data/file.bin");
  • type:二进制文件的类型,"standalone","firmware","kernel", "ramdisk", "flat_dt"等;
  • arch:平台类型,“arm”, "arm64", “i386”等;
  • os:操作系统类型,linux、vxworks等;
  • compression:二进制文件的压缩格式,SPL、或uboot会按照执行的格式解压;
  • load:二进制文件的加载位置,SPL、或uboot会把它copy对应的地址上;
  • entry:二进制文件入口地址,一般kernel image需要提供,uboot会跳转到该地址上执行;
  • hash:使用的数据校验算法。

具体可以参考:doc/uImage.FIT/source_file_format.txt。

(2) configurations节点

可以将不同类型的二进制文件,根据不同的场景,组合起来,形成一个个的配置项,u-boot在boot的时候,以配置项为单位加载、执行,这样就可以根据不同的场景,方便的选择不同的配置。下面是u-boot.its中的配置节点:

configurations {
        default = "config";
        config {
                description = "Rockchip armv8 with ATF";
                rollback-index = <0x0>;
                firmware = "atf@1";
                loadables = "uboot", "atf@2" , "atf@3" , "atf@4" , "atf@5" , "atf@6" ;
                fdt = "fdt";
                signature {
                        algo = "sh

你可能感兴趣的:(Rockchip RK3399 - TPL/SPL方式加载uboot)