ARM64 Trust Firmware [一]

ARMv8 启动流程:

在《RK3568上电启动流程 [十五]》中,简单介绍了 RK3568 的上电启动过程,本篇再详细分解其启动流程。

在 ARMv8 架构中,启动流程包含多个阶段,这些阶段被称为 BL (bootloader) 阶段:

  • BL1:第一阶段启动固件,在 RK3568 中位于 BootRom 中,负责引导 BL2 并对其进行安全验证;
  • BL2:第二阶段启动固件,在 RK3568 中位于 Flash 中(比如 eMMC),负责平台相关的初始化,比如 DRAM 的初始化,并负责加载 BL31 并执行 BL31,在 RK3568 中就是我们的 miniloader.bin;
  • BL31:也就是 trust Runtime firmware,BL31 是持久存在的可信固件,负责系统安全服务和在安全非非安全世界之间切换;
  • BL32:包含 TEE OS 和安全应用 TAs,运行在 EL1,启动 EL0 的安全应用,完成后返回 BL31;
  • BL33:非安全世界的启动固件,通常就是 U-Boot 或者直接启动 Linux 内核;

在 RK3568 中其启动全流程的输出如下:

在支持 ATF 的 ARMv8 中完整的镜像跳转流程如下:

ATF 编译和 uboot image 打包:

为了学习 ATMv8 Trust Firmware,最好的方法就是将开源的 ATF 编译,并在 RK3568 上跑起来,通过打印,调试去理解其工作机制。但是Upstream ARM Trusted Firmware 是不支持 RK3568 的,Rockchip 只提供了官方的 trust bin 文件(ATF - Rockchip open source Document)。但是最后发现在arm-trusted-firmware 的v2.12 版本中还是存在 RK3568 的 Platform,因此用 v2.12 来编译生成 bl31.elf,并将其打包进 uboot.img 中(后来发现该 bl31.elf 会导致 Linux 在初始化 SCMI 时失败,但是先不管了,至少我们可以有源码,并且能够编译和实现初步的运行)。

ATF 的编译:

bash 复制代码
git clone https://github.com/ARM-software/arm-trusted-firmware.git

cd arm-trusted-firmware
git checkout v2.12.0
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3568

将编译生成的 bl31.elf 拷贝到 u-boot 目录下。

uboot 使用 FIT Image 格式,所以我们需要先生成 u-boot.its,再使用 mkimage 工具根据 u-boot.its 文件做成 uboot.itb

uboot.its 如下:这里我将 OPTEE 的分支删除了,因为我们目前不需要研究 TEE OS。

bash 复制代码
/*
 * Copyright (C) 2020 Rockchip Electronic Co.,Ltd
 *
 * Simple U-boot fit source file containing ATF/OP-TEE/U-Boot/dtb/MCU
 */

/dts-v1/;

/ {
        description = "CXJ FIT Image with ATF/OP-TEE/U-Boot/MCU";
        #address-cells = <1>;

        images {
            uboot {
                description = "U-Boot";
                data = /incbin/("u-boot-nodtb.bin.gz");
                type = "standalone";
                arch = "arm64";
                os = "U-Boot";
                compression = "gzip";
                load = <0x00a00000>;
                digest {
                    value = /incbin/("./u-boot-nodtb.bin.digest");
                    algo = "sha256";
                };
                hash {
                    algo = "sha256";
                };
            };
            atf-1 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0x00040000.bin.gz");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "gzip";
                load = <0x00040000>;
                hash {
                    algo = "sha256";
                };
                digest {
                    value = /incbin/("./bl31_0x00040000.bin.digest");
                    algo = "sha256";
                };
            };
            atf-2 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0xfdcd0000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0xfdcd0000>;
                hash {
                        algo = "sha256";
                };
            };
            fdt {
                description = "U-Boot dtb";
                data = /incbin/("./u-boot.dtb");
                type = "flat_dt";
                arch = "arm64";
                compression = "none";
                hash {
                        algo = "sha256";
                };
            };
        };

        configurations {
            default = "conf";
            conf {
                description = "rk3568-evb";
                rollback-index = <0x0>;
                firmware = "atf-1";
                loadables = "uboot", "atf-2";

                fdt = "fdt";
                signature {
                    algo = "sha256,rsa2048";

                    key-name-hint = "dev";
                    sign-images = "firmware", "loadables", "fdt";
                };
            };
        };
};

再使用 mkimage 生成 u-boot.itb:

bash 复制代码
./tools/mkimage -f u-boot.its -E uboot.itb

通过 fdtdump 我们可以看到 uboot img 包含的内容:

bash 复制代码
cuixujia.cxj@localhost:~/workspace/luban/LubanCat_SDK/u-boot$ fdtdump uboot.itb

**** fdtdump is a low-level debugging tool, not meant for general use.
**** If you want to decompile a dtb, you probably want
****     dtc -I dtb -O dts <filename>

/dts-v1/;
// magic:               0xd00dfeed
// totalsize:           0x72f (1839)
// off_dt_struct:       0x38
// off_dt_strings:      0x66c
// off_mem_rsvmap:      0x28
// version:             17
// last_comp_version:   16
// boot_cpuid_phys:     0x0
// size_dt_strings:     0xc3
// size_dt_struct:      0x634

/ {
    version = <0x00000000>;
    totalsize = <0x00095f0d>;
    timestamp = <0x67adacea>;
    description = "CXJ FIT Image with ATF/OP-TEE/U-Boot/MCU";
    #address-cells = <0x00000001>;
    ...
    ...

重新烧录uboot.itb,重启后,我们可以看到系统可以成功加载 atf,uboot:

cpp 复制代码
Trying fit image at 0x4000 sector
## Verified-boot: 0
## Checking atf-1 0x00040000 (gzip @0x00240000) ... sha256(3a0e0e29a2...) + sha256(cb9e165ab3...) + OK
## Checking uboot 0x00a00000 (gzip @0x00c00000) ... sha256(69d1989cfb...) + sha256(5f44711400...) + OK
## Checking fdt 0x00b4b478 ... sha256(a474c6bb61...) + OK
## Checking atf-2 0xfdcd0000 ... sha256(e25f5f200c...) + OK
Jumping to U-Boot(0x00a00000) via ARM Trusted Firmware(0x00040000)
Total: 133.134/203.236 ms

NOTICE:  BL31: v2.12.0(release):v2.12.0
NOTICE:  BL31: Built : 10:51:56, Feb 13 2025
NOTICE:  BL31: Rockchip release version: v1.0
usb dr_mode not found
usb dr_mode not found


U-Boot 2017.09-dirty #cuixujia.cxj (Feb 13 2025 - 16:21:38 +0800)

Model: Rockchip RK3568 Evaluation Board

但是在 Linux bringup 过程中 hang 住了,由于开源 ATF 对 RK3568 支持不足,怀疑是在 SCMI 这块的支持有问题:

cpp 复制代码
[    3.068424] usbcore: registered new interface driver usbfs
[    3.068510] usbcore: registered new interface driver hub
[    3.068578] usbcore: registered new device driver usb
[    3.069218] mc: Linux media interface: v0.10
[    3.069293] videodev: Linux video capture interface: v2.00
[    3.069435] pps_core: LinuxPPS API ver. 1 registered
[    3.069459] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    3.069501] PTP clock support registered
[    3.069575] EDAC MC: Ver: 3.0.0
[    3.070837] arm-scmi firmware:scmi: SCMI Notifications - Core Enabled.

关于 FIT Image:

FIT(Flattened image tree)UImage,FIT 和 FDT 比较类似,利用的语法都是 Device Tree Source files 语法,生成的 image 文件也和 dtb 文件基本一样。

FIT uImage 的生成流程可以概括如下:

以 u-boot.its 的 uboot 节点为例,简述一下 its 的 语法结构:

bash 复制代码
    images {

        uboot {
            description = "U-Boot";
            data = /incbin/("u-boot-nodtb.bin.gz");
            type = "standalone";
            arch = "arm64";
            os = "U-Boot";
            compression = "gzip";
            load = <0x00a00000>;
            digest {
                value = /incbin/("./u-boot-nodtb.bin.digest");
                algo = "sha256";
            };
            hash {
                algo = "sha256";
            };
        };
  • description:子镜像文本的描述,可以随便写;
  • data:包含该节点二进制文件的路径;
  • type:子镜像类型;
  • compression:压缩方法,比如 gzip,bzip2 等;
  • load:二进制文件的内存加载位置;
  • hash:镜像使用的校验算法,如 sha256,crc32 等;
相关推荐
Ribou26 分钟前
Ubuntu 24.04.2安装k8s 1.33.4 配置cilium
linux·ubuntu·kubernetes
tan180°1 小时前
Boost搜索引擎 网络库与前端(4)
linux·网络·c++·搜索引擎
Mr. Cao code2 小时前
Docker:颠覆传统虚拟化的轻量级革命
linux·运维·ubuntu·docker·容器
抓饼先生2 小时前
Linux control group笔记
linux·笔记·bash
挺6的还3 小时前
25.线程概念和控制(二)
linux
您的通讯录好友3 小时前
conda环境导出
linux·windows·conda
代码AC不AC4 小时前
【Linux】vim工具篇
linux·vim·工具详解
码农hbk4 小时前
Linux signal 图文详解(三)信号处理
linux·信号处理
bug攻城狮4 小时前
Skopeo 工具介绍与 CentOS 7 安装指南
linux·运维·centos
宇宙第一小趴菜4 小时前
08 修改自己的Centos的软件源
linux·运维·centos