首页 > 系统相关 >转载-linux与soc-移植U-Boot思路和实践 | 基于RK3399

转载-linux与soc-移植U-Boot思路和实践 | 基于RK3399

时间:2023-06-17 22:12:45浏览次数:61  
标签:bin soc img Boot boot defconfig RK3399 rk3399

原文链接:https://mp.weixin.qq.com/s/T1BmaP2-XbJIpLNsFxKeEQ

0. 背景介绍

我们手里这块RK3399开发板出厂时带的是2017.09版本的U-Boot。

  1.   U-Boot 2017.09 (Sep 26 2021 - 08:53:15 +0000)
  2.    
  3.   Model: Forlinx OK3399 Evaluation Board
  4.   PreSerial: 2
  5.   DRAM:  2 GiB
  6.   Sysmem: init
  7.   Relocation Offset is: 7dbe9000
  8.   Using default environment

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

1. U-Boot加载方式

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

我们暂且先不关心如何加载操作系统镜像文件,这篇文章的目的是让新版本的U-Boot在这块板子上成功的运行起来。

既然U-Boot是bootloader,那么就不得不了解芯片上电后程序的加载流程。对于RK3399而言,关于它的启动方式请看前文:

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文件。

6c7d1fcdd45b2629eb45ceb9f256b925.png RK官方固件

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

  1.   tools/mkimage -n rkxxxx -T rksd -d rkxx_ddr_vx.xx.bin idbloader.img
  2.   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。

  1.   tools/mkimage -n rkxxxx -T rksd -d tpl/u-boot-tpl.bin idbloader.img
  2.   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
 

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

  1.   idbloader.img <--------U-Boot TPL/SPL
  2.   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.01。

  1.   # SPDX-License-Identifier: GPL-2.0+
  2.    
  3.   VERSION = 2022
  4.   PATCHLEVEL = 01
  5.   SUBLEVEL =
  6.   EXTRAVERSION =
  7.   NAME =

- step2

准备bl31.elf文件,如下:

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

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

  1.   rk@ubuntu:~/porting/u-boot$ ls ..
  2.   rk3399_bl31_v1.35.elf  u-boot
  3.   rk@ubuntu:~/porting/u-boot$export BL31=../rk3399_bl31_v1.35.elf

- step3

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

  1.   rk@ubuntu:u-boot$ ls configs/ | grep 3399
  2.   evb-rk3399_defconfig
  3.   ficus-rk3399_defconfig
  4.   firefly-rk3399_defconfig
  5.   khadas-edge-captain-rk3399_defconfig
  6.   khadas-edge-rk3399_defconfig
  7.   khadas-edge-v-rk3399_defconfig
  8.   leez-rk3399_defconfig
  9.   nanopc-t4-rk3399_defconfig
  10.   nanopi-m4-2gb-rk3399_defconfig
  11.   nanopi-m4b-rk3399_defconfig
  12.   nanopi-m4-rk3399_defconfig
  13.   nanopi-neo4-rk3399_defconfig
  14.   nanopi-r4s-rk3399_defconfig
  15.   orangepi-rk3399_defconfig
  16.   pinebook-pro-rk3399_defconfig
  17.   puma-rk3399_defconfig
  18.   rock960-rk3399_defconfig
  19.   rock-pi-4c-rk3399_defconfig
  20.   rock-pi-4-rk3399_defconfig
  21.   rock-pi-n10-rk3399pro_defconfig
  22.   rockpro64-rk3399_defconfig
  23.   roc-pc-mezzanine-rk3399_defconfig
  24.   roc-pc-rk3399_defconfig
  25.   rk@ubuntu:u-boot$

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

  1.   rk@ubuntu:~/porting/u-boot$ git log configs/evb-rk3399_defconfig
  2.   ...
  3.   commit 4473a1c4d648a0567c46333b81533d1030345e12
  4.   Author: Yifeng Zhao <yifeng.zhao@rock-chips.com>
  5.   Date:   Tue Jun 29 16:24:43 2021 +0800
  6.    
  7.       rockchip: config: evb-rk3399: add hs400 and SDMA support
  8.       
  9.       This enable hs400 and SDMA support for emmc on evb-rk3399.
  10.       
  11.       Signed-off-by: Yifeng Zhao <yifeng.zhao@rock-chips.com>
  12.       Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
  13.   ...
  14.   commit 5c5435093a6c0a6995351b64c6b8b08fe7d6bf59
  15.   Author: Kever Yang <kever.yang@rock-chips.com>
  16.   Date:   Tue Aug 11 14:47:01 2020 +0800
  17.    
  18.       rockchip: config: evb-rk3399: Add rockchip dwmmc support
  19.       
  20.       This enable support for SD card on evb-rk3399.
  21.       
  22.       Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
  23.   ...

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

make evb-rk3399_defconfig
 

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

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

编译结果:

  1.   ...
  2.     AR      tpl/fs/built-in.o
  3.     LD      tpl/u-boot-tpl
  4.     OBJCOPY tpl/u-boot-tpl-nodtb.bin
  5.     CAT     tpl/u-boot-tpl-dtb.bin
  6.     COPY    tpl/u-boot-tpl.bin
  7.     SYM     tpl/u-boot-tpl.sym
  8.     MKIMAGE u-boot-dtb.img
  9.   ./"arch/arm/mach-rockchip/make_fit_atf.py" \
  10.   arch/arm/dts/rk3399-evb.dtb > u-boot.its
  11.     MKIMAGE u-boot.itb
  12.     MKIMAGE tpl/u-boot-tpl-rockchip.bin
  13.     CAT     idbloader.img
  14.     CAT     u-boot-rockchip.bin
  15.   rk@ubuntu:~/porting/u-boot$

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

- step4

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

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

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

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

06f4f7f43b321b99b8665979d60f614e.png

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

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

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

  1.   [root@rk3399:/]# dd if=idbloader.img of=/dev/mmcblk2 seek=64
  2.   277+1 records in
  3.   277+1 records out
  4.   142034 bytes (142 kB, 139 KiB) copied, 0.00497 s, 28.6 MB/s
  5.   [root@rk3399:/]# 
  6.   [root@rk3399:/]# dd if=u-boot.itb of=/dev/mmcblk2 seek=16384
  7.   1503+1 records in
  8.   1503+1 records out
  9.   769952 bytes (770 kB, 752 KiB) copied, 0.0608755 s, 12.6 MB/s
  10.   [root@rk3399:/]# sync

- step5

重启开发板,从U-Boot版本和编译的时间戳可以确认,成功加载并执行了新的U-Boot 2022.01:

  1.   U-Boot 2022.01-00450-g25711b07ca (Jan 14 2022 - 09:37:38 +0800)
  2.    
  3.   SoC: Rockchip rk3399
  4.   Reset cause: RST
  5.   Model: Rockchip RK3399 Evaluation Board
  6.   DRAM:  2 GiB
  7.   PMIC:  RK808 
  8.   Core:  245 devices, 24 uclasses, devicetree: separate
  9.   MMC:   mmc@fe320000: 1, mmc@fe330000: 0
  10.   Loading Environment from MMC... OK
  11.   In:    serial
  12.   Out:   serial
  13.   Err:   serial
  14.   Model: Rockchip RK3399 Evaluation Board
  15.   Net:   eth0: ethernet@fe300000
  16.   Hit any key to stop autoboot:  0 
  17.   ......

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

5d71dfb8c47ec58d6ea140486265145d.png Maskrom模式

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

 

标签:bin,soc,img,Boot,boot,defconfig,RK3399,rk3399
From: https://www.cnblogs.com/stellarbin/p/17488344.html

相关文章

  • springboot注册过滤器
    springboot注册过滤器需要使用过滤器的话,优先选择拦截器。因为拦截器符合aop思想。在springboot中使用过滤器有三种方式。分别如下方式一:传统web在传统javaweb、ssm中使用过滤器差不多类似,这里以java配置为例,实现Filter接口@WebFilter("/*")publicclassMyFilter01i......
  • SpringBoot整合ActiveMQ
    第一步: 第二步: 第三步: 下面如有需要才使用 ......
  • Springboot整合mongodb
    入门案例创建工程,导入依赖导入依赖点击查看代码<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><version>2.3.9.RELEASE</version>......
  • How to enable auto restart of a docker container on system reboot ?
    Howtoenableautorestartofadockercontaineronsystemreboot ?https://amalgjose.com/2021/02/12/how-to-enable-auto-restart-of-a-docker-container-on-system-reboot/#:~:text=How%20to%20enable%20auto%20restart%20of%20a%20docker,Ensure%20the%20docker%20co......
  • SpringBoot--MQ不生效
    Cannotresolveconfigurationproperty'rabbitmq.username'rabbitmq:username:adminpassword:adminvirtual-host:test_datalistener:simple:#表示消费者消费成功消息以后需要手工的进行签收(ack确认),默认为autoacknowledge-mode:manualprefet......
  • springboot @Bean自动注册
    这个注解,可以注册Bean到spring容器中@BeanpublicXXXBeanxxxBean(){returnnewXXXBean();}这个注解也可以用在void方法上,用在在spring容器启动后固定执行某个代码逻辑:@BeanpublicvoidxxxHandler(){System.out.println("我想容器启动后执行一次某个代......
  • SpringBoot学习笔记
    新建SpringBoot项目阿里云地址:https://start.aliyun.com异常消息处理//1.自定义异常类,继承RuntimeExceptionpublicclassMyExceptionextendsRuntimeException{publicMyException(){}}//2.定义全局异常类@RestControllerAdvicepublicclassGloabExcept......
  • Spring Boot实现高质量的CRUD-5
    (续前文)9、Service实现类代码示例 ​​ 以用户管理模块为例,展示Service实现类代码。用户管理的Service实现类为UserManServiceImpl。​UserManServiceImpl除了没有deleteItems方法外,具备CRUD的其它常规方法。实际上​UserManService还有其它接口方法,如管理员修改密码,用户修改自身......
  • WebSocket的使用
    例子://WebSocket构造函数,创建WebSocket对象letws=newWebSocket('ws://localhost:8888')//连接成功后的回调函数ws.onopen=function(params){console.log('客户端连接成功')//向服务器发送消息ws.send('hello')};//从服务器接受到信息时的回调函数ws......
  • SpringBoot整合JavaMail
    第一步:第二步: 第三步:第四步: ......