Firefly-RK3399平台移植U-boot 2022.10

Firefly-RK3399平台移植U-boot 2022.10


文章目录

  • Firefly-RK3399平台移植U-boot 2022.10
    • 背景介绍
    • U-Boot加载方式
      • 1.1 官方固件加载
      • 1.2 TPL/SPL加载
    • 2. U-Boot包
    • 3.移植U-Boot
    • 后记


背景介绍

Firefly-RK3399出场自带的U-Boot是2017.09

Firefly-RK3399平台移植U-boot 2022.10_第1张图片

U-Boot 2017.09 (Jul 05 2018 - 15:12:31)

Model: Firefly-RK3399 Board
PreSerial: 2
DRAM: 3.9 GiB
Sysmem: init
Relocation Offset is: 7dbe9000
Using default environment

在这个基础之上为这块开发板移植一个最新版本的U-Boot,也就是 U-Boot 2022.10

U-Boot加载方式

U-Boot实质是bootloader,它一肩挑两头,第一是初始化操作系统的运行环境,包括初始化CPU、内存、串口等,第二是加载操作系统镜像文件,通常来说是操作系统内核镜像,但对于U-Boot SPL而言,它还可以加载U-Boot镜像文件。

暂且先不关心如何加载操作系统镜像文件,这篇文章的目的是让新版本的U-Boot在这块板子上成功的运行起来。既然U-Boot是bootloader,那么就不得不了解芯片上电后程序的加载流程。

参考瑞芯微wiki

  • use U-Boot TPL/SPL from upsream or rockchip U-Boot, fully source code;
  • use Rockchp idbLoader which is combinded by Rockchip ddr init bin and miniloader bin from Rockchip rkbin project;

Firefly-RK3399平台移植U-boot 2022.10_第2张图片

从eMMC/SD/U-Disk/net启动时,会有不同的启动内容:

  • Stage 1 is always in boot rom, it loads stage 2 and may load stage 3(when SPL_BACK_TO_BROM option enabled).
  • Boot from SPI flash means firmware for stage 2 and 3(SPL and U-Boot only) in SPI flash and stage 4/5 in other place;
  • Boot from eMMC means all the firmware(including stage 2, 3, 4, 5) in eMMC;
  • Boot from SD card means all the firmware(including stage 2, 3, 4, 5) in SD card;
  • Boot from U-Disk means firmware for stage 4 and 5(not including SPL and U-Boot) in Disk, optionally only including stage 5;
  • Boot from net/tftp means firmeware for stage 4 and 5(not including SPL and U-Boot) on the network;

RK3399提供了外部bootloader加载的路线图,如下图示:

Firefly-RK3399平台移植U-boot 2022.10_第3张图片启动流程

按照路线图,分两部分介绍,分别是官方固件和TPL/SPL加载U-Boot。

1.1 官方固件加载

流程1是基于RK官方部件ddr.bin和miniloader.bin来实现的,这两个文件可以从RK github上获取。

[email protected]:rockchip-linux/rkbin.git

这个仓库除了包含以上两个文件之外,还包括流程2中提到的bl31.elf文件。

Firefly-RK3399平台移植U-boot 2022.10_第4张图片

RK官方固件

使用mkimage将官方的ddr.bin和rkxx.bin打包成Bootrom程序可识别的、带有ID Block header的文件idbloader.img。

tools/mkimage -n rkxxxx -T rksd -d rkxx_ddr_vx.xx.bin idbloader.img
cat rkxx_miniloader_vx.xx.bin >> idbloader.img

idbloader.img打包完成之后,由其中的rkxx_miniloader_xxx.bin加载u-boot.img文件。
另外,基于流程1的启动方式,还需要再生成trust.img,由rkxx_miniloader_xxx.bin负责加载。
流程1这种启动方式毕竟是基于官方固件的,不能对代码进行修改,看不见摸不到,所以不建议采用这种方式生成idbloader.img。

1.2 TPL/SPL加载

在启动流程2中,我们可以基于U-Boot编译出TPL/SPL,其中TPL负责实现DDR初始化,TPL初始化结束之后会回跳到bootrom程序,bootrom程序继续加载SPL,由SPL加载u-boot.itb文件。

通过以下命令将TPL/SPL打包成idbloader.img。

tools/mkimage -n rkxxxx -T rksd -d tpl/u-boot-tpl.bin idbloader.img
cat spl/u-boot-spl.bin >> idbloader.img

建议使用流程2的方式加载U-Boot.img,因为,可以基于U-Boot源码编译出TPL/SPL,然后自主修改各种配置。

2. U-Boot包

从RK3399启动流程图中我们能看到,U-Boot包里面除了u-boot.dtb和u-boot-nodtb.bin这两个U-Boot源码编译出来的文件之外,还包含了bl31.elf、bl32.bin、tee.bin等ARM trust固件。其中bl31.elf是必须要有的,bl32.bin、tee.bin是可选的,可以没有。

在使用TrustZone技术的嵌入式设备当中,无法避免的需要解决从非安全侧切换到安全侧的问题,而为了完成这个切换,需要一个专用的进行非安全上下文和安全上下文切换的固件,这个固件一般我们称为arm trust firmware,在ARM官方维护的github中我们能够下载到其完整的代码。

https://github.com/ARM-software/arm-trusted-firmware

当然RK官方也提供了bl31.elf文件,这样省去了我们编译bl31.elf的时间和精力。可以在Rockchip官方github下载

https://github.com/rockchip-linux/rkbin/tree/master/bin/rk33

基于以上的分析,整理出所需要的文件:

idbloader.img <--------U-Boot TPL/SPL
u-boot.itb <-----------U-Boot 和 bl31.elf

3.移植U-Boot

  • step1
    获取U-Boot源码,如下:
git clone https://gitlab.denx.de/u-boot/u-boot.git

获取到的U-Boot源码版本是2022.10。

# SPDX-License-Identifier: GPL-2.0+

VERSION = 2022
PATCHLEVEL = 10
SUBLEVEL =
EXTRAVERSION =
NAME =
  • step2
    准备bl31.elf文件,如下:
git clone [email protected]:rockchip-linux/rkbin.git

进入到u-boot文件夹设置bl31.elf文件的路径。

original@ubuntu22:/work/rock_uboot$ ls ..
rk3399_bl31_v1.35.elf  u-boot
original@ubuntu22:/work/rock_uboot$export BL31=../rk3399_bl31_v1.35.elf
  • step3
    编译

手头没有这块板子的xxx_defconfig文件,但是从U-Boot源码中查看到很多其他家板子的xxx_defconfig文件

original@ubuntu22:/work/rock_uboot$ ls configs/ | grep rk3399
eaidk-610-rk3399_defconfig
evb-rk3399_defconfig
ficus-rk3399_defconfig
firefly-rk3399_defconfig
khadas-edge-captain-rk3399_defconfig
khadas-edge-rk3399_defconfig
khadas-edge-v-rk3399_defconfig
leez-rk3399_defconfig
nanopc-t4-rk3399_defconfig
nanopi-m4-2gb-rk3399_defconfig
nanopi-m4b-rk3399_defconfig
nanopi-m4-rk3399_defconfig
nanopi-neo4-rk3399_defconfig
nanopi-r4s-rk3399_defconfig
orangepi-rk3399_defconfig
pinebook-pro-rk3399_defconfig
puma-rk3399_defconfig
rock960-rk3399_defconfig
rock-pi-4c-rk3399_defconfig
rock-pi-4-rk3399_defconfig
rock-pi-n10-rk3399pro_defconfig
rockpro64-rk3399_defconfig
roc-pc-mezzanine-rk3399_defconfig
roc-pc-rk3399_defconfig
original@ubuntu22:/work/rock_uboot$ 

log记录来看,firefly-rk3399_defconfig应该是Firefly官方提交的,因此,选择这个xxx_defconfig文件作为默认config

original@ubuntu22:/work/u-boot-rockchip$ git log configs/firefly-rk3399_defconfig
commit 1247c35c80cb0f6f17c88d54c6575d6d1f50c608
Author: Tom Rini 
Date:   Tue Aug 23 15:24:14 2022 -0400

    configs: Resync with savedefconfig
    
    Rsync all defconfig files using moveconfig.py
    
    Signed-off-by: Tom Rini 

commit 6600b355c71e80c99d8edb8603dd5e3df8ed4db8
Author: Tom Rini 
Date:   Fri May 27 10:19:45 2022 -0400

    Convert CONFIG_SPL_BSS_START_ADDR to Kconfig
    
    This converts the following to Kconfig:
       CONFIG_SPL_BSS_START_ADDR
    
    Signed-off-by: Tom Rini 

commit f113d7d3034672de7d074506a05a7055f1f0dcae
Author: Tom Rini 
Date:   Thu May 26 13:13:21 2022 -0400

    Convert CONFIG_SPL_STACK to Kconfig
    
    This converts the following to Kconfig:
       CONFIG_SPL_STACK
    
    Signed-off-by: Tom Rini 

commit eaf6ea6a1dc10d49cdcbcad0f8b0abb6c1eb1db1
Author: Tom Rini 
Date:   Wed May 25 12:16:03 2022 -0400

    Migrate CUSTOM_SYS_INIT_SP_ADDR to Kconfig using system-constants.h
    
    - Make all users of CUSTOM_SYS_INIT_SP_ADDR reference SYS_INIT_SP_ADDR
    - Introduce HAS_CUSTOM_SYS_INIT_SP_ADDR to allow for setting the stack
      pointer directly, otherwise we use the common calculation.
    - On some platforms that were using the standard calculation but did not
      set CONFIG_SYS_INIT_RAM_SIZE / CONFIG_SYS_INIT_RAM_ADDR, set them.
    - On a small number of platforms that were not subtracting
      GENERATED_GBL_DATA_SIZE do so now via the standard calculation.
    - CONFIG_SYS_INIT_SP_OFFSET is now widely unused, so remove it from most
      board config header files.
    
    Signed-off-by: Tom Rini 

commit 9b5f9aeb3b48dbc059272168635a397ea5096a31
Author: Tom Rini 
Date:   Thu May 19 15:09:22 2022 -0400

    Convert CONFIG_SPL_BSS_MAX_SIZE et al to Kconfig
    
    This converts the following to Kconfig:
       CONFIG_SPL_BSS_MAX_SIZE
       CONFIG_SPL_MAX_FOOTPRINT
    
    Note that the da850evm platforms were violating the "only use one" rule
    here, and so now hard-code their BSS limit.
    
    Signed-off-by: Tom Rini 

commit ca8a329a1b7f3195ee56fee4c0906ee883383dfa
Author: Tom Rini 
Date:   Mon May 16 17:20:26 2022 -0400

    Convert CONFIG_SPL_PAD_TO et al to Kconfig
    
    This converts the following to Kconfig:
       CONFIG_SPL_PAD_TO
       CONFIG_SPL_MAX_SIZE
       CONFIG_TPL_PAD_TO
       CONFIG_TPL_MAX_SIZE
    
    Note that we need to make TPL_MAX_SIZE be hex, and so move and convert the
    existing places.
    
    Signed-off-by: Tom Rini 

生成默认配置文件,如下:

make firefly-rk3399_defconfig

编译U-Boot,交叉编译工具链:aarch64-linux-gnu-gcc在Makefile中
Firefly-RK3399平台移植U-boot 2022.10_第5张图片
编译结果:

...
  AR      tpl/fs/built-in.o
  LD      tpl/u-boot-tpl
  OBJCOPY tpl/u-boot-tpl-nodtb.bin
  CAT     tpl/u-boot-tpl-dtb.bin
  COPY    tpl/u-boot-tpl.bin
  SYM     tpl/u-boot-tpl.sym
  MKIMAGE u-boot-dtb.img
./"arch/arm/mach-rockchip/make_fit_atf.py" \
arch/arm/dts/rk3399-evb.dtb > u-boot.its
  MKIMAGE u-boot.itb
  MKIMAGE tpl/u-boot-tpl-rockchip.bin
  CAT     idbloader.img
  CAT     u-boot-rockchip.bin
  original@ubuntu22:/work/rock_uboot$ 

至此,我们已经获取到了所需的idbloader.imgu-boot.itb两个文件。

  • step4
    烧录

firefly-rk3399开发板基于emmc启动,按照RK官方要求将idbloader.img烧录到emmc0x40扇区,u-boot.itb烧录到0x4000扇区。

Firefly-RK3399平台移植U-boot 2022.10_第6张图片

烧录方法有两种,一种是基于RK的官方烧录工具AndroidTool.exe,另外一种是在开发板上直接烧写emmc
官方AndroidTool.exe是基于recovery模式实现的,如果你的板子带有recovery按键,可以使用这种方式。

Firefly-RK3399平台移植U-boot 2022.10_第7张图片

开发板上直接烧写emmc,可以通过网络或者串口直接将待烧录文件加载到板子中。

[root@rk3399:/]# lrz 
lrz waiting to receive.
Starting zmodem transfer.  Press Ctrl+C to cancel.
Transferring idbloader.img...
  100%     138 KB     138 KB/sec    00:00:01       0 Errors  Transferring u-boot.itb...
  100%     751 KB     150 KB/sec    00:00:05       0 Errors  
[root@rk3399:/]#

烧写,需要注意的是烧写完执行sync操作,否则,可能会烧写失败。

[root@rk3399:/]# dd if=idbloader.img of=/dev/mmcblk2 seek=64277+1 records in277+1 records out
142034 bytes (142 kB, 139 KiB) copied, 0.00497 s, 28.6 MB/s
[root@rk3399:/]# 
[root@rk3399:/]# dd if=u-boot.itb of=/dev/mmcblk2 seek=163841503+1 records in1503+1 records out
769952 bytes (770 kB, 752 KiB) copied, 0.0608755 s, 12.6 MB/s
[root@rk3399:/]# sync
  • step5
    重启开发板,从U-Boot版本和编译的时间戳可以确认,成功加载并执行了新的U-Boot 2022.10:
U-Boot 2022.10-g85a8ef12-dirty (Nov 26 2022 - 00:43:23 +0800)

SoC: Rockchip rk3399
Reset cause: POR
Model: Firefly-RK3399 Board
DRAM:  3.9 GiB
PMIC:  RK808 
Core:  281 devices, 28 uclasses, devicetree: separate
MMC:   mmc@fe310000: 3, mmc@fe320000: 1, mmc@fe330000: 0
Loading Environment from MMC... *** Warning - bad CRC, using default environment

In:    serial@ff1a0000
Out:   serial@ff1a0000
Err:   serial@ff1a0000
Model: Firefly-RK3399 Board
Net:   eth0: ethernet@fe300000
Hit any key to stop autoboot:  0 
......

最后要说的是,敢这么胡乱搞开发板的固件,并不担心它会成为一块砖头,因为,有Maskrom模式可以将它恢复出厂设置。

Firefly-RK3399平台移植U-boot 2022.10_第8张图片下载后启动串口输出:
Firefly-RK3399平台移植U-boot 2022.10_第9张图片U-boot启动后输可以看到版本信息和编译时间,但是发现 g85a8ef12-dirty,这个字符串是为了提示当前工程中没有git commmit,解生成原理是在Makefile中产生的,了解详细过程的可以分享一下。

使用的U-boot 2022.10代码git路径

Maskrom模式另外,移植的U-Boot是基于firefly-rk3399_defconfig生成的配置文件,后面基于此进行其他修改,也可以创建属于自己的单板。

后记

对于新接触的开发板来说,官方的文档都是第一手资料,比如怎么重新烧写整个系统,怎么更新等注意事项,阅读官方手册是最好的捷径。

参考资料

Firefly-RK3399
firefly 3399 开发板笔记

你可能感兴趣的:(Firefly-RK3399,linux,java,运维)