锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

移植U-Boot思路和实践 | 基于RK3399

时间:2023-04-07 16:07:00 ross高继电器e12

0. 背景介绍

这一块在我们手里RK2017年3399开发板出厂时带.09版本的U-Boot。

U-Boot2017.09(Sep262021-08:53:15 0000)  Model:ForlinxOK3399EvaluationBoard PreSerial:2 DRAM:2GiB Sysmem:init RelocationOffsetis:7dbe9000 Usingdefaultenvironment

在此基础上,移植最新版本的开发板U-Boot,也就是U-Boot 2022.01

1. U-Boot加载方式

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

我们暂时不在乎如何加载操作系统的镜像文件。本文的目的是使新版本U-Boot在这块板上成功运行。

既然U-Boot是bootloader,然后我们必须了解芯片上电后程序的加载过程。RK至于3399,关于它的启动方式,请参阅以下内容:

CPU上电后加载程序的流程 | 基于RK3399

RK3399提供了外部bootloader如下图所示:

9b757d463ce87f6030d9f607f427ebc7.png
启动流程

根据路线图,分为官方固件和两部分TPL/SPL加载U-Boot。

1.1 加载官方固件

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

git@github.com:rockchip-linux/rkbin.git

除上述两份文件外,仓库还包括流程2中提到的内容bl31.elf文件。

RK官方固件

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

tools/mkimage-nrkxxxx-Trksd-drkxx_ddr_vx.xx.binidbloader.img catrkxx_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加载

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

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

tools/mkimage-nrkxxxx-Trksd-dtpl/u-boot-tpl.binidbloader.img catspl/u-boot-spl.bin>>idbloader.img

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

2. U-Boot包

从RK我们可以在3399启动流程图中看到,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-BootTPL/SPL u-boot.itb<-----------U-Boot和bl31.elf

3.移植U-Boot

- step1

获取U-Boot源代码如下:

gitclonehttps://gitlab.denx.de/u-boot/u-boot.git

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

#SPDX-License-Identifier:GPL-2.0   VERSION=2022 PATCHLEVEL=01 SUBLEVEL= EXTRAVERSION= NAME=

- step2

准备bl31.elf文件如下:

gitclonegit@github.com:rockchip-linux/rkbin.git

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

rk@ubuntu:~/porting/u-boot$ls.. rk3399_bl31_v1.35.elfu-boot rk@ubuntu:~/porting/u-boot$exportBL31=../rk3399_bl31_v1.35.elf

- step3

编译
手头没有这块板xxx_defconfig文件,但从U-Boot在源码中查看了许多其他板块xxx_defconfig文件。

rk@ubuntu:u-boot$lsconfigs/|grep3399 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-k3399_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
rk@ubuntu:u-boot$

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

rk@ubuntu:~/porting/u-boot$ git log configs/evb-rk3399_defconfig
...
commit 4473a1c4d648a0567c46333b81533d1030345e12
Author: Yifeng Zhao 
Date:   Tue Jun 29 16:24:43 2021 +0800

    rockchip: config: evb-rk3399: add hs400 and SDMA support
    
    This enable hs400 and SDMA support for emmc on evb-rk3399.
    
    Signed-off-by: Yifeng Zhao 
    Reviewed-by: Kever Yang 
...
commit 5c5435093a6c0a6995351b64c6b8b08fe7d6bf59
Author: Kever Yang 
Date:   Tue Aug 11 14:47:01 2020 +0800

    rockchip: config: evb-rk3399: Add rockchip dwmmc support
    
    This enable support for SD card on evb-rk3399.
    
    Signed-off-by: Kever Yang 
...

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

make evb-rk3399_defconfig

编译U-Boot,交叉编译工具链使用了开发板自带的,它又不是全局环境变量,懒得改了,直接用。当然,大家可以使用自己的交叉编译工具链。

# 交叉编译工具链需要指定
make CROSS_COMPILE=xxxx/aarch64-linux-gnu-

编译结果:

...
  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
rk@ubuntu:~/porting/u-boot$

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

- step4

烧录
我手中这块开发板基于emmc启动,按照RK官方要求将idbloader.img烧录到emmc的0x40扇区,u-boot.itb烧录到0x4000扇区。

+--------+----------------+----------+-------------+---------+
| Boot   | Terminology #1 | Actual   | Rockchip    | Image   |
| stage  |                | program  |  Image      | Location|
| number |                | name     |   Name      | (sector)|
+--------+----------------+----------+-------------+---------+
| 2      |  Secondary     | U-Boot   |idbloader.img| 0x40    |
|        |  Program       | TPL/SPL  |             |         |
|        |  Loader (SPL)  |          |             |         |
|        |                |          |             |         |
| 3      |  -             | U-Boot   | u-boot.itb  | 0x4000  | 
|        |                |          | uboot.img   |         | 
+--------+----------------+----------+-------------+---------+

烧录方法有两种,一种是基于RK的官方烧录工具AndroidTool.exe,另外一种是在开发板上直接烧写emmc。

官方AndroidTool.exe是基于recovery模式实现的,如果你的板子带有recovery按键,可以使用这种方式。

开发板上直接烧写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=64
277+1 records in
277+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=16384
1503+1 records in
1503+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.01:

U-Boot 2022.01-00450-g25711b07ca (Jan 14 2022 - 09:37:38 +0800)

SoC: Rockchip rk3399
Reset cause: RST
Model: Rockchip RK3399 Evaluation Board
DRAM:  2 GiB
PMIC:  RK808 
Core:  245 devices, 24 uclasses, devicetree: separate
MMC:   mmc@fe320000: 1, mmc@fe330000: 0
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Model: Rockchip RK3399 Evaluation Board
Net:   eth0: ethernet@fe300000
Hit any key to stop autoboot:  0 
......

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

Maskrom模式

另外,移植的U-Boot是基于evb-rk3399_defconfig生成的配置文件,后面基于此进行其他修改。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章