​平台:orangepi4 rockchip rk3399 LPDDR4 4G eMMC 16G

系统:ubuntu 20.04

主要介绍移植最新的bootloader到RK3399,我使用的是orangepi4主板。RK3399的uboot采用的方案有两种:瑞芯微原厂提供的idbloader.bin方案和uboot TPL/SPL方案

idbloader.bin方案是基于rkbin项目,这段代码是不开源的,对于我们想研究齐原理部分不是很方便,本文不做讨论,idbloader.bin方案移植可以参考uboot编译移植

瑞芯微还提供了一种采用U-Boot TPL/SPL 模式的开源uboot方案,参考官方移植,本文就是参考官网的移植方法进行移植,对于出现的问题进行修改,以达到启动的目的

1.RK3399上电启动过程

对于CPU来说实际上第一个阶段就是CPU刚启动的时候的bootrom阶段,这段代码是固化在CPU内部,CPU上电后自动将内部ROM的代码拷贝到SRAM的0xFFFF0000处然后执行。这段程序的功能是:程序首先做一些判断,程序会判断SPI Flash/eMMC/SDCard里面是否存在及里面是否有uboot固件,如果存在,读取固件到SRAM,然后程序到转到uboot的固件里面执行,这里只是读取了uboot前面的一小部分,因为毕竟内部SRAM空间是有限的(只有192KB,上电后被映射到了0xffff0000) ,假如这时候eMMC存在并且里面有程序,则idbloader.bin或TPL这部分代码就会被拷贝到SRAM并执行,如果所有的存储设备都找不到程序,则CPU会进入到一个模式叫MASKROM模式,此时USB会被设置成Device模式,使用瑞芯微的工具可以进行固件升级。

从这里可以看出bootrom内的程序是包含了SPI、eMMC、SDCard及USB设备驱动程序的,但是不包含对DDR的初始化。

2. uboot的启动阶段

主要是三个阶段:TPL SPL UBOOT

TPL阶段 意思是这样Target Program Loader,就是芯片级的初始化过程,这个时候的代码都是基于芯片平台的部分,此时出现在芯片的内部SRAM里面运行,主要的工作就是做一些CPU芯片的初始化、内存的初始化以及存储设备驱动加载。如果内存初始化失败则不能进入下一阶段,这一部分的代码相对独立,不能共用,对于RK3399来说,其代码就在arch\arm\mach-rockchip目录里面。

SPL阶段 指的是Secondary Program Loader 第二阶段程序加载器,主要是进行存储设备的初始化eMMC、SD等,这个阶段的目的主要是将存储设备的程序拷贝到DDR里面去,这一部分代码基本上是还可以通用,所以放在第二阶段来处理,这一步执行仍然是在CPU内部的SRAM中进行。

UBOOT阶段 这时候才是进行真正的uboot执行这部分的代码大部分都是通用的。

瑞芯微提供的idbloader.bin固件实际上是执行了前面的两个阶段任务,第三阶段代码实际上是一样的。

3.固件升级方式

通常我们是用瑞芯微提供的Linux下的工具rkdeveloptool进行升级,首先要知道rkdeveloptool是基于什么情况下才会起作用的,是在CPU进入MASKROM模式后而且跟主机通过USB连接,因为这个时候主板的DDR并没有初始化,而升级过程是需要很大的内存空间的,所以升级之前第一步要做的就是执行rkdeveloptool db rkxx_loader_vx.xx.bin ,这个固件其实就是idbloader.bin只不过这时候只是在内存中执行,如果不执行db命令的话其他的命令则无法执行因为没有做内存初始化工作。

按照开头uboot编译移植获取rkdeveloptool工具及rk3399_loader_v1.2x.bin文件

4. ATF移植

因为 RK3399 是 Arm64,所以我们还需要编译 ATF (Arm trust firmware), ATF 主要负责在启动 U-Boot 之前把 CPU 从安全的 EL3 切换到 EL2,然后跳转到 U-Boot,并且在内核启动后负责启动其他的 CPU。

ATF将系统启动从最底层进行了完整的统一划分,将secure monitor的功能放到了bl31中进行,这样当系统完全启动之后,在CA或者TEE OS中触发了smc或者是其他的中断之后,首先是遍历注册到bl31中的对应的service来判定具体的handle,这样可以对系统所有的关键smc或者是中断操作做统一的管理和分配。ATF的code boot整个启动过程框图如下:

这个固件对于uboot来说不是必须的,但是如果不添加会导致内核无法启动,我之前没有添加就导致进入内核时卡住了启动不了,会停在Starting kernel ...这个地方

具体论述可以参考正点原子的关于STM32MP1开发板linux驱动教程第六章的说明STM32MP1嵌入式Linux驱动开发指南V2.0-嵌入式文档类资源-CSDN下载

安装工具:

sudo apt-get install gcc-arm-none-eabi gcc-aarch64-linux-gnu

下载源码:

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

编译:

选择编译平台rk3399和编译器

make PLAT=rk3399 CROSS_COMPILE=aarch64-linux-gnu-

编译成功后会在build/rk3399/release/bl31/目录下生成一个bl31.elf文件

4.uboot移植

移植采用的是eMMC方式,其他方式类似

下载源码

git clone https://gitlab.denx.de/u-boot/u-boot.git

查看Makefile版本号是 2022.01

将bl31.elf文件拷贝到uboot代码根目录

配置

选择一个配置版本,查看configs文件夹中RK3399的配置文件,要选择一个适的DDR版本的配置,因为我使用的是LPDDR4的板子,所以查看

grep -r "LPDDR4" configs/

一个LPDDR4开关打开的配置,因为我没有找到orangepi4的配置文件,所以我使用了另一个常用的开发板的配置

make nanopi-r4s-rk3399_defconfig

编译

make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu-

编译成功后会生成idbloader.img u-boot.itb 这时候的idbloader.img文件并非通过rkbin工程得到的,而是由TPL/SPL两个文件组合起来的,实际的构建方式是:

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

2022.01版本这里是自动生成的,在Makefile 1462行:

u-boot.itb也是自动生成的,在Makefile 1426行:

u-boot.itb实际上是u-boot.img的另一个变种,也是通过mkimage构建出来的,依赖于u-boot.its u-boot.dtb u-boot-nodtb.bin这三个文件,主要是为了支持DeviceTree新内核架构,实际上是通过mkimage fit的方法实现的,基于u-boot.its文件,可以查看u-boot.its文件:

/** This is a generated file.*/
/dts-v1/;/ {description = "FIT image for U-Boot with bl31 (TF-A)";#address-cells = <1>;images {uboot {description = "U-Boot (64-bit)";data = /incbin/("u-boot-nodtb.bin");type = "standalone";os = "U-Boot";arch = "arm64";compression = "none";load = <0x00200000>;};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>;};atf_2 {description = "ARM Trusted Firmware";data = /incbin/("bl31_0xff3b0000.bin");type = "firmware";arch = "arm64";os = "arm-trusted-firmware";compression = "none";load = <0xff3b0000>;};atf_3 {description = "ARM Trusted Firmware";data = /incbin/("bl31_0xff8c0000.bin");type = "firmware";arch = "arm64";os = "arm-trusted-firmware";compression = "none";load = <0xff8c0000>;};fdt_1 {description = "rk3399-khadas-edge.dtb";data = /incbin/("arch/arm/dts/rk3399-khadas-edge.dtb");type = "flat_dt";compression = "none";};};configurations {default = "config_1";config_1 {description = "rk3399-khadas-edge.dtb";firmware = "atf_1";loadables = "uboot","atf_2","atf_3";fdt = "fdt_1";};};};

具体构建过程可参见uboot构建框架6-u-boot.bin生成过程追踪_sunxiaohusunke的专栏-CSDN博客_uboot.bin

烧录

进入MaskRom模式,将EMMC_CLKO这个信号接地上电后就会进入MaskRom模式,注意此时不要插SD卡,我测试如果插SD卡是不会进入MaskRom模式的

sudo rkdeveloptool db rk3399_loader_v1.25.126.bin
sudo rkdeveloptool wl 0x40 idbloader.img
sudo rkdeveloptool wl 0x4000 u-boot.itb
sudo rkdeveloptool rd

上电

给开发板上电,通过串口打印输出

分析

通过串口发现TPL阶段执行完毕,DDR初始化成功,在进入SPL后MMC读取错误,eMMC应该是有一个通用的驱动程序来驱动,虽然芯片可能不会不一样不是一个厂商但是其接口操作方式应该是一样的不然CPU上电第一步也不会认到eMMC了,重点查看驱动有没有加载。

查看rk3399.dtsi找到emmc设备对应的compatible是arasan,sdhci-5.1通过查找发现其驱动是在drivers\mmc\rockchip_sdhci.c 在rockchip_sdhci_probe添加打印函数:

重新编译后下载发现并没有打印,这说明驱动并没有加载成功,所以要一步步查找了。有一种解决方法是先换一种配置方案,我换了一个配置khadas-edge-rk3399_defconfig,这时候有打印信息出来:

说明这个配置是有用的,但是还是不能启动,打开rockchip_sdhci.c Debug信息(不能打开所有的debug函数,因为这样操作会有问题,具体原因还不清楚,我的做法是把单个文件里面的debug函数全部替换成printf函数)发现:

先不管这么多把return -ENODEV;屏蔽掉:

这时候发现了没检测到上电:

这应该是跟寄存器有关,查看struct rockchip_emmc_phy定义

这个指针应该是指向一个寄存器,经过查看发现phy指针是在rk3399_emmc_get_phy()函数中赋值的,因为RK3399有一个General Register Files 的struct rk3399_grf_regs寄存器表,这是一个全局静态结构体,指向通用寄存器地址,所以phy指针应该是指向这个寄存器表里面的某一个区域,

因为在rk3399_emmc_get_phy()函数通过 syscon_get_first_range获取寄存器表指针并没有报错,所以应该是priv->phy指向有错误

通过查询RK3399TRM手册发现EMMCPHY_CON0的偏移地址是0x0f780

我在这里直接将grf_phy_offset=0x0f780;然后重新编译:

成功进入命令行!!!

这时候再来找一下为何nanopi-r4s-rk3399_defconfig配置不行的原因,查看nanopi-r4s-rk3399_defconfig找到DEVICE_TREE配置

打开rk3399-nanopi-r4s.dts发现emmc_phy、sdhci是disable的,把它们改成okay后重新编译后发现就正常啦,关于dts原理后面会讲到。

这是我从源头开始移植uboot的记录,其中也不乏一些分析调试的过程,有时候想解决一个问题确实不是那么简单,不知道从什么地方入手,但是按部就班的去做,总是能找到方法突破点,当然我的上面还有一些未解决的问题,没有找到emmc_phy设备的问题,后面有时间再拿出来研究,有什么问题欢迎指正。

嵌入式ARM64 uboot 2022.01 移植相关推荐

  1. 移植Kdump至嵌入式ARM64环境

    工欲善其事,必先利其器.操作系统崩溃是高级Linux运维工程师很头疼的事情,但也不要害怕,前辈们已经给我们磨了好多把刀,其中有一把叫做Kdump.目前在主流的Linux发行版如Ubuntu.Cento ...

  2. 《安富莱嵌入式周报》第251期:2022.01.31--2022.02.06

    往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...

  3. 《安富莱嵌入式周报》第249期:2022.01.17--2022.01.23

    往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...

  4. 嵌入式linux之Uboot和系统移植--基础

    <uboot和系统移植-第1部分-uboot学习前传> (观看朱友鹏老师视频后整理的笔记)   1.为什么要有uboot 2.为什么是uboot 3.uboot必须解决哪些问题 4.ubo ...

  5. 《安富莱嵌入式周报》第248期:2022.01.10--2022.01.16

    往期周报汇总地址:链接 目录 本周发布了两期视频教程: 视频版 图文版 1.ARM第一款采用新安全分区架构的Morello评估板现已交付给研究人员 2.三星实现基于MRAM的内存计算设备 3.Qt6. ...

  6. 《安富莱嵌入式周报》第247期:2022.01.03--2022.01.09

    往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...

  7. 嵌入式linux usb wifi驱动移植

    文档名称:嵌入式linux usb wifi驱动移植 版本历史 版本号        时间        内容 v1.0b001        2012-6-18        初始版本,介绍在嵌入式 ...

  8. x210:uboot和系统移植

    注:本文是对朱老师uboot和系统移植课程的备忘引导性笔记,主要是为了能够在学完后快速回忆起相关内容.本文主要记录了一些关键易忘性知识点并包含少量理解性内容,遵循尽量精简的原则,以尽量少的篇幅概括整个 ...

  9. uboot和系统移植-第1部分-2.1 uboot学习前传

    uboot和系统移植-第1部分-2.1 uboot学习前传 第一部分.章节目录 2.1.1. 为什么要有uboot (1)uboot最主要作用是用来启动操作系统内核.因为操作系统内核本身不能自己启动自 ...

最新文章

  1. flutter 类似日期选择器控件_一切皆组件的Flutter,安能辨我是雄雌
  2. python中re_Python中re(正则表达式)模块学习
  3. 实验报告:抽象数据类型的表现和实现
  4. 运行shell脚本报错:“syntax error near unexpected token fi 的解决方法
  5. html表格输入框怎么左移动,当我向CSS中的文本框添加边框时,HTML表单输入会移动...
  6. SpringMVC中@Controller和@RequestMapping
  7. 暴涨2000+? 2021年软件测试平均薪资出来了,我坐不住了
  8. 《学习之道》第十二章练习困难的部分
  9. vue 第十天 (组件的基本使用)
  10. java 类中 serialversionuid 作用
  11. java 集合的并交差_java中计算集合的交差并集示例代码
  12. 54 小明的存钱计划
  13. R语言入门——猜数小游戏
  14. c代码实现 ifft运算_二维FFT,IFFT,c语言实现 | 学步园
  15. Python实现一篇txt文章的词频统计:文件读取+字典
  16. androidstudio使用Svn忽略文件
  17. 【已解决】在react+ts中 atnd 用 upload 组件报错Failed to execute ‘readAsArrayBuffer,param 1 is notof type Blob
  18. 使用cpolar发布群晖NAS上的网页(2)
  19. PR导出错误怎么办?解决PR导出视频提示“编译影片时出错“ GPU渲染错误 错误代码:-1609629695
  20. SpringMVC——对Ajax的处理(包含 JSON )

热门文章

  1. 什么是全量备份,增量备份,差异备份?
  2. stm32串口接收不到数据的一些问题
  3. 小学奥数的学习路径是什么
  4. 第一章:Reac入门 与 第二章:React面向组件编程
  5. Sysmac Studio过期后解决方法
  6. 按p出现仅计算机然后黑屏了,电脑开机黑屏,提示按任意键继续,怎么破?
  7. Convention
  8. 倪文迪陪你学蓝桥杯2021寒假每日一题:1.21日(2018省赛A组第9题)
  9. 你的学识能否撑起你的智商?
  10. 无线测试软件市场份额,USBType C的应用方向及市场规模 - 关于USB Type C技术、应用和产业链的最强解读...