【RK3399】RK3399启动引导流程分析

00. 目录

01. RK3399概述

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

主要特性

  • Dual-core Cortex-A72 up to 1.8GHz
    Quad-core Cortex-A53 up to 1.4GHz
  • NPU up to 3.0TOPS
  • Mali-T860MP4 GPU
  • Dual-channel DDR3/DDR3L/LPDDR3/LPDDR4
  • 4K UHD H265/H264/VP9
  • HDR10/HLG
  • H264 encoder
  • Dual MIPI CSI and ISP
  • USB Type-C

详细参数

在这里插入图片描述

02. SOC启动流程

2.1 BootROM介绍

一般来说,SoC厂家都会做一个ROM在SoC的内部,这个ROM很小,里面固化了上电启动的代码(一经固化,永不能改,是芯片做的时候,做进去的);这部分代码呢,我们管它叫做BootROM,也叫作一级启动程序。

2.2 初始化硬件

芯片上电后先接管系统的是SoC厂家的BootROM,它主要初始化系统,CPU 的配置,关闭看门狗,初始化时钟,初始化一些外设(比如 USB Controller、MMC Controller,Nand Controller 等);

2.3 加载程序到SRAM

当我们拿到一款新的SoC时,都会进行电路原理图设计,我们一般会在芯片外挂一些存储设备(eMMC、Nand、Nor、SDCard等)和内存(SDRAM、DDR等)电路图绘制好了。我们接着会绘制电路板,制作出板子。

有了板子还不行,我们还得往里面烧写程序。这个烧写程序,其实就是将可执行的二进制文件写到外部的存储设备上(eMMC、Nand、SD等)。系统上电启动的时候,会将他们读到内存中执行。

前面我们说了,上电后先接管系统的是SoC厂家的BootROM,其它可执行的程序(u-boot、Kernel)都放(烧写)到了外部存储器是先去执行 上;那么BootROM的代码除了去初始化硬件环境以外,还需要去外部存储器上面,将接下来可执行的程序读到内存来执行。

既然是读到内存执行,那么这个内存可以不可以是我们板载的 DDR呢?理论上是可以的,但是,SoC 厂家设计的DDR控制器呢,一般会支持很多种类型的DDR设备,并且会提供兼容性列表,SoC厂家怎么可能知道用户PCB上到底用了哪种内存呢?所以,直接把外部可执行程序读到DDR显然是不太友好的,一般来说呢,SoC都会做一个内部的小容量的SRAM ,BootROM将外部的可执行程序从外部存储器中读出来,放到SRAM去执行;

好了,现在我们引出了SRAM,引出了BootROM;那么 BootROM从具体哪个存储器读出二进制文件呢?SoC 厂家一般会支持多种启动方式,比如从eMMC 读取,从SDCard读取,从Nand Flash 读取等等;上电的时候,需要告诉它,它需要从什么样的外设来读取后面的启动二进制文件;

一般的设计思路是,做一组 Bootstrap Pin,上电的时候呢?BootROM去采集这几个IO的电平,来确认要从什么样的外部存储器来加载后续的可执行文件;比如呢,2 个 IO,2’b00 表示从Nand 启动,2’b01表示从eMMC 启动,2’b10 表示从SDCard 启动等等;

当 BootROM读到这些值后,就会去初始化对应的外设,然后来读取后面要执行的代码;这些 IO一般来说,会做成板载的拨码开关,用于调整芯片的启动方式;

这里,读取烧写的二进制的时候呢,需要注意一些细节,比如SoC 厂家告诉你,你需要先把SDCard初始化称为某种文件系统,然后把东西放进去才有效,之类的;因为文件系统是组织文件的方式,并不是裸分区;你按照A文件系统的方式放进去,然后 SoC 的 BootROM也按照 A 文件系统的方式读出来,才能够达成一致;

如果你对Mini2440这款开发板足够了解的话,你应该知道其采用的SoC型号为s3c2440,其内部有一个4kb的SRAM。其有两种启动方式:

  • 采用Nor Flash启动,0x00000000就是2MB Nor Flash实际的起始地址,由于uboot程序一般只有几百kb,可以全部烧录到Nor Flash中,因此uboot程序完全可以在Nor Flash中运行,没有拷贝到SDRAM中运行的必要;
  • 采用Nand Flash启动,片内4KB的SRAM被映射到了0x00000000,s3c2440的BootROM会自动把Nand Flash中的前4kb代码数据搬到内部SRAM中运行,那么问题来了,假设4KB代码运行到最后,我想继续运行Nand Flash剩余的代码怎么办?为了解决这个问题,uboot引入了SPL,全称Secondary Program Loader。

注意:无论是Nor Flash还是Nand Flash都是外挂在s3c2440上的的存储设备。

03. SPL介绍

前面说了,芯片上电后BootROM会根据 Bootstrap Pin 去确定从某个存储器来读可执行的二进制文件到SRAM并执行;理论上来说,这个二进制文件就可以是我们的u-boot.bin文件了;也就是 BootROM 直接加载u-boot.bin;

理论上是这样的,但是这里有一个问题,就是SRAM很贵,一般来说,SoC的片上 SRAM 都不会太大,一般4KB、8KB、16KB…256KB不等;但是呢,u-boot 编译出来却很大,好几百KB,放不下,就像我上面说的s3c2440的例子那样。

放不下怎么办?有两种办法:

  • 假设片内SRAM为4KB,uboot的前4KB程序实现uboot的重定位,即将uboot拷贝到SDRAM中运行;
  • 做一个小一点的boot程序,先让BootROM加载这个小的程序,后面再由这个小boot去加载uboot;

3.1 方案一

比如,我们的uboot有400KB,SRAM有4KB,外部SDRAM有64MB:如果使用第一种方案的话,uboot的前面4KB被加载进入SRAM 执行,uboot 被截断,我们就需要保证在uboot的前4KB代码,把板载的 SDRAM初始化好,把整个uboot拷贝到SDRAM,然后跳转到SDRAM执行;

比如我们之前介绍的Mini2440开发板从Nand Flash启动时,uboot程序就是采用的这种实现方式。

3.2 方案二

第二种方案的话,我们做一个小的uboot ,这个uboot就叫做SPL(Secondary Program Loader),它很小很小(小于SRAM大小),它先被BootROM加载到SRAM运行,那么这个SPL要做什么事情呢?最主要的就是要初始化内存控制器,然后将真正的大u-boot从外部存储器读取到SDRAM中,然后跳转到大uboot。

04. RK3399启动流程

在这里插入图片描述

如上图所示:

  • (0)上电后,BootROM开始执行,初始化时钟,关闭看门狗,关 Cache,关中断等等,根据 Bootstrap Pin 来确定启动设备,初始化外设;

  • (1) 使用外设驱动,从存储器读取SPL;

    ---------------- 以上部分是 SoC 厂家的事情,下面是用户要做的事情 ----------------

  • (2) SPL被读到SRAM 执行,此刻,控制权以及移交到我们的SPL 了;

  • (3) SPL初始化外部SDRAM;

  • (4) SPL使用驱动从外部存储器读取uboot并放到SDRAM;

  • (5) 跳转到SDRAM中的uboot执行;

  • (6) 加载内核;

实际情况中,还需注意很多问题:

  • 编译阶段的链接地址,是否需要地址无关?
  • SPL的代码和uboot的代码是否有重合的地方?如果有,是否意味着SPL执行过的,跳转到uboot又要在执行一次?
  • 具体情况下,需要配置哪些硬件?怎么配置?

05. RK3399地址空间

5.1 地址映射

RK3399支持从内部BootROM启动,并且支持通过软件编程进行地址重映射。重映射是通过SGRF_PMU_CON0[15]控制的,当重映射设置为0是,地址0xFFFF0000被映射到BootROM,当重映射设置为1时,0xFFFF0000被映射到片内SRAM。

在这里插入图片描述

从这张图我们可以看到在进行重映射前:

  • 0x0000 0000 ~ 0xF800 0000:为DDR内存空间;
  • 0xFF8C 0000 ~ 0xFF98 0000:片内SRAM内存空间,一共192KB;
  • 0xFFFF 0000~ 0xFFFF 8000:为BootROM内存空间,一共32KB;
  • 其它空间:用于一些特定功能;

如果进行了地址重映射:

  • BootROM被映射到地址0xFFFD 0000;
  • 片内SRAM被映射到地址0xFFFF 0000;

06. 系统启动

RK3399提供从片外设备启动系统,如serial nand or nor flash、eMMC、SD/MMC卡。当这些设备中的启动代码没有准备好时,还可以通过 USB OTG 接口将系统代码下载到各个外设存储中。

所有引导代码都将存储在内部 BootROM中。其中支持以下功能:

(1) 支持安全启动模式和非安全启动模式;
(2) 支持系统从以下设备启动;

  • SPI接口;
  • eMMC接口;
  • SD/MMC卡;

(3) 支持系统代码通过USB OTGF下载;
以下是存储在BootROM中的启动代码的整个启动过程:
在这里插入图片描述

从图中可以得到以下几个结论:

(1) 上电后, A53核心从0xffff0000这个地址读取第一条指令,这个内部BootROM在芯片出货的时候已经由原厂烧写;

(2) 然后依次从Nor Flash、Nand Flash、eMMC、SD/MMC获取ID BLOCK,ID BLOCK正确则启动,都不正确则从USB端口下载;

  • 如果eMMC启动,则先读取SDRAM(DDR)初始化代码到内部SRAM,由于SRAM只有192KB,因此最多只能读取那么多,然后初始化DDR,再将eMMC上的代码(剩下的用户代码)复制到DDR运行;
  • 如果从USB下载,则先获取DDR初始化代码,下载到内部SRAM中,然后运行代码初始化DDR,再获取loader代码(用户代码),加载到DDR中并运行;

07. Rockchip引导流程

参考: Rockchip引导流程

针对不同的解决方案,Rockchip提供了两种不同的启动加载程序方法,其步骤和生成的镜像文件也是完全不同的。

  • TPL/SPL加载:使用Rockchip官方提供的TPL/SPL U-boot(就是我们上面说的小的uboot),该方式完全开源;
  • 官方固件加载:使用Rockchip idbLoader,它由 Rockchip rkbin project 的Rockchip ddr init bin和miniloader bin组合而成,该方式不开源;

需要注意的是:并不是所有平台都支持这两种启动加载程序方法。

上面我们介绍了SPL,那什么是TPL?实际上将我们上面所说的SPL初始化SDRAM等硬件工作的部分独立出去,就是TPL。那么我们总结一下:

  • TPL是Targer Program Loader,就是芯片级的初始化过程,这个时候的代码都是基于芯片平台的部分,它在启动过程中进行DDR初始化和一些其他的系统配置,以便后续的SPL能够正确地运行;
  • SPL是Secondary Program Loader,它从存储设备中读取trust(如ATF/OP-TEE)和uboot二进制文件,将它们加载到系统内存中并运行它们,进而启动完整的操作系统;

TPL和SPL的区别在于它们的职责不同。TPL主要负责初始化系统硬件,而SPL负责加载和运行其它软件组件,如trust和uboot。此外,在一些特殊情况下,如加密启动或安全启动模式下,TPL还可能执行其他额外的任务。

7.1 启动阶段

Rockchip处理器启动可以划分为5个阶段:

+--------+----------------+----------+-------------+---------+
| Boot   | Terminology #1 | Actual   | Rockchip    | Image   |
| stage  |                | program  |  Image      | Location|
| number |                | name     |   Name      | (sector)|
+--------+----------------+----------+-------------+---------+
| 1      |  Primary       | ROM code | BootROM     |         |
|        |  Program       |          |             |         |
|        |  Loader        |          |             |         |
|        |                |          |             |         |
| 2      |  Secondary     | U-Boot   |idbloader.img| 0x40    | pre-loader
|        |  Program       | TPL/SPL  |             |         |
|        |  Loader (SPL)  |          |             |         |
|        |                |          |             |         |
| 3      |  -             | U-Boot   | u-boot.itb  | 0x4000  | including u-boot and atf
|        |                |          | uboot.img   |         | only used with miniloader
|        |                |          |             |         |
|        |                | ATF/TEE  | trust.img   | 0x6000  | only used with miniloader
|        |                |          |             |         |
| 4      |  -             | kernel   | boot.img    | 0x8000  |
|        |                |          |             |         |
| 5      |  -             | rootfs   | rootfs.img  | 0x40000 |
+--------+----------------+----------+-------------+---------+

当我们讨论从eMMC/SD/U盘/网络启动时,它们涉及到不同的概念:

  • 第一阶段始终在BootROM中,它加载第二阶段并可能加载第三阶段(当启用SPL_BACK_TO_BROM选项时);
  • 从SPI闪存启动意味着第二阶段和第三阶段固件(仅限SPL和U-Boot)在SPI闪存中,第四/五阶段在其他位置;
  • 从eMMC启动意味着所有固件(包括第二、三、四、五阶段)都在eMMC中;
  • 从SD Card启动意味着所有固件(包括第二、三、四、五阶段)都在SD Card 中;
  • 从U盘启动意味着第四和第五阶段的固件(不包括SPL和U-Boot)在磁盘中,可选地仅包括第五阶段;
  • 从Net/TFTP启动意味着第四和第五阶段的固件(不包括SPL和U-Boot)在网络上。

启动阶段涉及到了多个镜像文件:

  • 阶段一中的BootROM这个是SoC厂商提供的,我们不用关心;
  • 阶段二方式需要提供一个idbloader.img,这个我们后面具体说说;
  • 阶段三实际上就是uboot的镜像文件了,这里又搞出了两种,uboot.img(还需要搭配trust.img)和u-boot.itb(这个是因为它已经把ATF打包进去了);这两个文件里面除了都包含u-boot.bin原始二进制文件,又放了点其他东西,可以被idbloader.img识别,然后加载,这个我们后面具体说说;
  • 阶段四和阶段五是内核镜像和根文件系统;

这里我们具体说一下阶段二,阶段三涉及到的几个镜像文件。

idbloader.img

idbloader.img文件是一个Rockchip格式的预加载程序,在SoC启动时工作,它包含:

  • 由Rockchip BootROM知道的IDBlock 头;
  • DDR初始化程序,由BootROM加载到SRAM,运行在SRAM内部;
  • 下一级加载程序,由MaskROM加载并运行在DDR上;

u-boot.img

u-boot.bin 是uboot源码编译后生成的原始二进制映像,可以直接烧录到设备的闪存中。而u-boot.img则是通过mkimage工具在u-boot.bin基础上增加了一个头部信息,这个头部信息可能也包括一些额外的数据,例如启动参数和内核映像地址等。
因此,通过使用u-boot.img而不是 u-boot.bin,可以使引导ROM更容易地识别uboot映像,并更好地指导uboot在设备上正确启动。

u-boot.itb

u-boot.itb实际上是u-boot.img的另一个变种,也是通过mkimage构建出来的,里面除了u-boot.dtb和u-boot-nodtb.bin这两个uboot源码编译出来的文件之外,还包含了bl31.elf、bl32.bin、tee.bin等ARM trust固件。其中bl31.elf是必须要有的,bl32.bin、tee.bin是可选的,可以没有。

trust.img

因为RK3399是ARM64,所以我们还需要编译 ATF (ARM Trust Firmware),ATF 主要负责在启动uboot之前把CPU从安全的EL3切换到 EL2,然后跳转到uboot,并且在内核启动后负责启动其他的CPU。

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

在这里插入图片描述

7.2 引导流程

Rockchip提供了外部uboot加载的流程图,如下图示:

在这里插入图片描述

如上图所示:

  • 引导流程1是典型的使用Rockchip miniloader的Rockchip引导流程;
  • 引导流程2用于大多数SoC,使用U-Boot TPL进行DDR初始化,使用SPL加载加载u-boot.itb文件;

注1:如果loader1具有多个阶段,则程序将返回到BootROM,BootROM将载入并运行到下一个阶段。例如,如果loader1是TPL和SPL,则BootROM将首先运行到TPL,TPL初始化DDR并返回到BootROM,BootROM然后将加载并运行到SPL。

注2:如果启用了trust,在安全模式(armv8中的EL3)下,loader1需要同时加载trust和U-Boot,然后运行到trust中,trust在非安全模式(armv8中的EL2)下进行初始化,并运行到U-Boot。

注3:对于trust(在trust.img或u-boot.itb中),armv7仅有一个带或不带TA的tee.bin,armv8具有bl31.elf并且可选包含bl32。

注4:在boot.img中,内容可以是Linux的zImage和其dtb,可以选择grub.efi,也可以是AOSP boot.img,ramdisk可选。

7.3 TPL/SPL方式

在TPL/SPL加载方式中,我们基于uoot源码编译出TPL/SPL,其中:TPL负责实现DDR初始化,TPL初始化结束之后会回跳到BootROM程序,BootROM程序继续加载SPL,由SPL加载u-boot.itb文件。

TPL:被BootROM加载到内部SRAM,起始地址为0xff8c2000;结束地址不能超过0xff980000,所以TPL程序最大不能超过184KB;

SPL:被BootROM加载到DDR,起始地址为0x00000000;结束地址绝对不能超过0x00040000, 因为0x00040000地址被用来加载bl31_0x00040000.bin, 因此SPL程序最大不能超过256KB:反汇编如下:

0000000000000000 <__image_copy_start>:
       0:       14000001        b       4 <__image_copy_start+0x4>
       4:       14000009        b       28 <reset>

0000000000000008 <_TEXT_BASE>:
        ...

0000000000000010 <_end_ofs>:
      10:       0001c618        .inst   0x0001c618 ; undefined
      14:       00000000        udf     #0

0000000000000018 <_bss_start_ofs>:
      18:       00400000        .inst   0x00400000 ; undefined
      1c:       00000000        udf     #0

0000000000000020 <_bss_end_ofs>:
      20:       004003c0        .inst   0x004003c0 ; undefined
      24:       00000000        udf     #0

0000000000000028 <reset>:
      28:       1400010a        b       450 <save_boot_params>

000000000000002c <save_boot_params_ret>:
      2c:       10007ea0        adr     x0, 1000 <vectors>
      ......

这里我们具体说一下采用这种方式RK3399的启动流程:

  • BootROM首先将eMMC中0x40扇区开始的184KB数据加载到片内SRAM中;由于TPL和SPL加在一起是超过184KB的,所以无法全部加载到SRAM,但是把TPL全部加载到SRAM中还是绰绰有余的,这里加载地址为0xff8c2000;
  • BootROM跳转到0xff8c2000执行TPL代码,主要是DDR的初始化,当然还有一些其他硬件的初始化;需要注意的是,执行完TPL代码之后,会返回到BootROM程序,你把它当做汇编指令bl TPL那样会更好理解;
  • BootROM加载SPL代码到DDR中,这里加载地址为0x00000000,然后跳转到地址0x00000000去执行,需要注意的是这个时候不会再返回到BootROM了,因此SPL会初始化eMMC并将eMMC中0x4000扇区的uboot加载到0x00200000地址处,然后跳转到该处执行uboot程序;

补充说明:上面描述的只是一个大概流程,当然中间SPL还会加载bl31.bin(bl32.bin、tee.bin非必须)去执行,但是这不是重点,所以就不做概述。

由于BootROM不是开源的,我们没法去研究BootROM源码,当然也我们可以修改common/spl/spl.c文件board_init_r函数在SPL代码执行时将地址0x000000000、0xff8c2000、0x40000000等地址数据打印出来(printf函数要加在boot_from_devices函数执行之后),和源二进制文件进行比对来验证自己的猜想:

board_init_r
addr 0x00000000 = 0x14000001   # 和u-boot-spl.bin前4字节匹配
addr 0x00000004 = 0x14000009   # 和u-boot-spl.bin文件偏移0x4处的4个字节匹配
addr 0x00000008 = 0x0          # 同样匹配
addr 0x00040000 = 0xaa0003f4   # 和bl31_0x00040000.bin文件前4字节匹配
addr 0x00050018 = 0xb8656883   # 和bl31_0x00040000.bin文件偏移0x10018处的4个字节匹配
addr 0xff8c2000 = 0x33334b52   # 这个地址数据和u-boot-tpl.bin有点对不上,可能后期被改变了?可以尝试在TPL阶段代码执行时输出这个看看

在该方式中,我们需要用到以下源代码:

  • uboot源码:编译生成u-boot-spl.bin、u-boot-tpl.bin、u-boot-nodtb.bin、u-boot.dtb;
  • ATF源码:编译生成bl31.elf;

通过编译和工具我们最终可以生成:

  • idbloader.img :由u-boot-spl.bin、u-boot-tpl.bin通过工具合并得到;
  • u-boot.itb:由bl32.elf、u-boot-nodtb.bin、u-boot.dtb、u-boot.its通过工具合并得到;

7.4 官方固件方式

在官方固件加载方式中,我们基于Rockchip rkbin官方给的ddr.bin、miniloader.bin来实现的;

(1) 通过tools/mkimage将官方固件ddr, miniloader打包成BootROM程序可识别的、带有ID Block header的文件idbloader.img;

  • ddr.bin:等价于上面说的TPL,用于初始化DDR;
  • miniloader.bin:Rockchip修改的一个bootloader,等价于上面说的SPL,用于加载uboot;

这个文件打包出来实际上也是超过192KB的,因此也是分为二阶段执行的。

(2) 通过tools/loaderimage工具将u-boot.bin打包成u-boot.img;其中u-boot.bin是由uboot源码编译生成;

补充说明:使用Rockchip miniloader的 idbloader 时,需要将u-boot.bin通过tools/loaderimage转换为可加载的miniloader格式。

(3) 使用Rockchip工具tools/trust_merge将bl31.bin打包成trust.img;其中bl31.bin由ATF源码编译生成;

补充说明:使用Rockchip miniloader的idbloader 时,需要将bl31.bin通过tools/trust_merge转换为可加载的miniloader格式。

08. 问题讨论

09. 参考

(1) rk3399移植 u-boot

(2) u-boot (3) — spl

(3) Rockchip Boot option

(4) U-Boot 之一 源码文件、启动阶段(TPL、SPL)、FALCON、设备树

(5) RK3399 TRM

(6) RK3399 Datasheet

(7) [Rockchip RK3399TRM V1.3 Part1.pdf](https://www.t-firefly.com/download/Firefly-RK3399/docs/TRM/Rockchip RK3399TRM V1.3 Part1.pdf)

(8) [Rockchip RK3399TRM V1.3 Part2.pdf](https://www.t-firefly.com/download/Firefly-RK3399/docs/TRM/Rockchip RK3399TRM V1.3 Part2.pdf)

### RK3399 设备刷机教程 对于RK3399设备的刷机过程,具体操作如下: #### 准备工作 确保拥有正确的刷机文件。例如,针对Firefly RK3399 PC Pro Android 10版本,image位于特定路径`rockdev/Image-rk3399_roc_pc_plus/ROC-RK3399-PC-Pro_Android10_HDMI_221130.img`[^1]。 #### USB连接与环境准备 nanoPC上电并通过USB线缆将其连接至宿主计算机(推荐使用Windows操作系统)。随后解压缩刷机包`rk3399-usb-friendlydesktop-bionic-4.4-arm64-20220919`中的文件,在此过程中定位到名为`RKDevTool`的应用程序并启动它。此时可能会提示未检测到任何设备,这属于正常现象,因为还需要进一步的操作来使工具识别目标硬件[^2]。 #### 启动模式切换 为了能够被RKDevTool成功探测,需按照指导调整nanoPC的状态:保持按下Recovery按钮的同时长时间(超过1.5秒)按住电源键开启机器,并且在此期间持续按着Reset按键直到指示灯亮起后再释放所有按键。当RKDevTool界面显示出已找到相应设备时,则表明已经进入了合适的刷写状态,可继续下一步骤。 #### 开始刷入固件 一旦确认RKDevTool能正确识别待刷写的NanoPC-T4或其他兼容型号后,在软件内的“下载镜像”标签页里选择之前提到过的`.img`格式系统映像文件作为要传输的数据源,点击“执行”。整个烧录流程可能耗时几分钟不等,请耐心等待直至完成消息弹出为止。 #### 编译自定义U-Boot (可选) 如果有特殊需求想要定制化引导加载程序的话,可以从官方获取最新的U-Boot源代码库开始着手。编译完成后得到两个重要的二进制组件——TPL(SPL前驱)用于早期内存配置以及SPL本身负责后续阶段的任务处理。这两个部分最终会被打包成单个`idbloader.img`文件供实际部署使用。创建该复合型映像的具体命令如下所示: ```bash tools/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin idbloader.img cat spl/u-boot-spl.bin >> idbloader.img ``` 上述指令通过调用`mkimage`工具指定平台名(`rk3399`)、类型(`rksd`)并将初始TPL映像加入新构建的目标文件内;紧接着追加SPL数据片段形成完整的IDBLoader结构体[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沧海一笑-dj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值