一篇搞懂RK3568从启动到OS全过程:存储角度
1 RK3568框图本文从程序在不同存储其中的运行跳转来理解RK3568启动的全过程。访问地址框图https://www.rock-chips.com/uploads/pdf/2022.8.26/191/RK3568%20Brief%20Datasheet.pdfTRM Part1https://opensource.rock-chips.com/images/2/26/Rockchip_RK3568_TRM_Part1_V1.3-20220930P.PDF上电boot流程BootROM映射到物理地址0xFFFF0000CPU从0xFFFF0000读取第一条指令并执行可执行程序角度BootROM - TPL(ddr.binDDR初始化) - SPL(spl.bin加载后续镜像) - Trust(ARM Trust Firmware OP-TEE安全) - U-Boot加载内核 - Kernel运行内核存储角度BootROM - SRAM(TPL) - SRAM(SPL) DDR(SPL) - DDR(Trust) - DDR(U-Boot)镜像本质二进制文件的一种组织形式作用CPU从存储设备中读取镜像文件获取二进制可执行程序入口跳转执行种类TPLSPLUBootTrustKernel目录2 boot流程帮助理解boot的启动流程3 RK3568物理地址空间设计帮助理解CPU如何从BootROM读取指令并执行帮助理解CPU如何访问SRAM帮助理解CPU如何访问DDR内存4 存储分区帮助理解镜像数据在存储设备中的分布5 BootROM帮助立即存储在MaskROM存储设备中的程序的执行流程6 SRAM帮助理解运行在SRAM中的TPL和SPL如果支持重定位SPL会把代码搬移到DDR中执行的执行流程7 DDR帮助理解运行在DDR内存中的UBoot的执行流程2 boot流程RK3568开源方案BootROM - TPL - SPL - Trust - UBoot - KernelRK3568闭源方案MaskROM - ddr.bin - miniloader.bin - Trust - UBoot - Kernelboot执行流程CPU从0xFFFF0000获取第一条指令并执行BootROM代码依次检查SPI Nor FlashSPI NAND FlashNAND FlasheMMC FlashSD卡USB OTAG从存储器中读取ID BLOCK并进行检查和校验加载DDRTPL初始化代码到SRAM中并执行加载SPL代码到DDR中并执行加载UBoot到DDR中并执行加载Kernel跳转到Kernel执行3 RK3568物理地址空间设计物理地址分布DDR内存区域外设寄存器SRAM区域BooROM区域boot地址映射remap[1:0]2’b00BootRom(20KB) : 0xFFFF0000PMU_SRAM(8KB) : 0xFDCD0000SYSTEM_SRAM (64KB) : 0xFDCC0000remap[1:0]2’b11BootRom(20KB) : 不可访问PMU_SRAM(8KB) 0xFFFF0000PMU_SRAM(8KB) 0xFDCD0000SYSTEM_SRAM (64KB) 0xFDCC0000remap[1:0]2’b10BootRom(20KB) 不可访问SYSTEM_SRAM (64KB) 0xFFFF0000PMU_SRAM(8KB) 0xFDCD0000SYSTEM_SRAM (64KB) 0xFDCC0000外设空间映射TRM Part1的Addresss Mapping章节PCIe超过4G空间的地址PCIe内存空间: 这是“数据窗口”CPU 读写这个窗口就是在读写 PCIe 设备. CPU 直接访问 PCIe 设备上的 BAR 空间如显卡的显存- PCIe2x1_S: 0x300000000- PCIe3x1_S: 0x340000000- PCIe3x2_S: 0x380000000-PCIe配置空间: 这是“控制面板”用来配置控制器本身和发现/配置 PCIe 设备. CPU 访问 PCIe 控制器自身的配置寄存器或通过控制器间接访问 PCIe 设备的配置空间- PCIe2x1_DBI: 0x3C0000000- PCIe3x1_DBI: 0x3C0400000- PCIe3x2_DBI: 0x3C08000004 存储分区默认分区映射表https://opensource.rock-chips.com/wiki_Partitions注意事项一级引导是MiniLoader则loader2可存放uboot.imgtrust分区可存放trust.img一级引导是不支持安全可信固件的SPL则loader2分区可存放u-boot.bin无可用trust分区一级引导式支持安全可信固件的SPL搭载ATF或OPTEE则loader2分区用于存放u-boot.itb内含u-boot.bin与可信固件二进制文件无可用trust分区RK使用GPT分区表https://github.com/rockchip-linux/u-boot/blob/android/doc/README.gpt4.1 不同存储介质的ID BLOCK偏移eMMC芯片- 首先需要了解eMMC芯片的结构- 从boot扇区加载, 也就是从0扇区加载- 扇区 64 0x40同 SDeMMC 的 user data areaSD卡- 前置空间需要放置MBR- 扇区 64 0x4032KB 偏移SPI Nor Flash- 起始扇区 00x0 偏移, SPI 无扇区概念按字节/页读- rkspi 每 4KB 只用前 2KB 做 spread镜像翻倍- rknand 按 pagesize/skippages 做 spreadSPI NAND Flash- 存在坏块管理, 从逻辑0扇区加载, 可设置备份分区- 起始页 00x0 偏移但有跳页要求: NAND pagepagesize如2KB/4KBNAND Flash- 起始页 0同 SPI NAND跳页4.2 不同介质的本质区别SD/eMMC 用扇区 640x40SD/eMMC 的前 64 个扇区32KB是 MBR/GPT 分区表区域BootROM 跳过分区表从扇区 64 开始读 ID Blockdoc/README.rockchip:296 明确“rksd.c produces an image consisting of 32KB of empty space, a header and u-boot-spl-dtb.bin”——这 32KB 空白就是留给分区表的SD/eMMC 是块设备有分区表MBR/GPTBootROM 必须跳过分区表才能放引导代码所以固定从扇区 64 开始SPI Nor / NAND 从起始0x0读SPI/NAND 没有分区表的概念BootROM 直接从介质最起始处读 ID Blockdoc/README.rockchip:323“The image should be written to the start of SPI flash.”SPI Nor 是线性字节设备没有分区表从 0 开始即可NAND 的位置还要考虑坏块和跳页NAND 有坏块BootROM 读取时会跳过坏块NAND 的 page 结构要求 spreadSPI NAND / 并行 NAND 是页设备没有分区表从 page 0 开始但要处理坏块和页对齐4.3 镜像打包相关代码关键文件不同介质的封装差异uboot/tools/rksd.c、rkspi.c、rknand.c扇区偏移文档uboo/doc/README.rockchip镜像打包逻辑uboot/make.sh 的打包逻辑5 BootROMBootROM执行流程BootROM被映射到物理地址0xFFFF0000CPU从0xFFFF0000读取指令并执行CPU从存储设备中读取ID BLOCK并校验校验成功加载TPL前置分析BootROM不可修改由于它首先要加载ID BLOCK而其支持的存储设备有很多SPI Nor FlashSPI NAND FlashNAND FlasheMMC FlashSD卡所以它只能从固定位置访问ID BLOCK对于不同的存储器我们要掌握这个固定位置的设计这是确保系统能正常启动的第一步ID BLOCK是校验镜像合法性的第一步ID BLOCK的组成也是镜像启动的关键一步校验成功后开始加载TPL。BootROM如何知道从存储器的什么位置加载TPL在ID BLOCK的位置不变的情况下扩展性的最好的设计就是通过在镜像头部记录不同镜像的offset依此来定位镜像的位置。所以镜像的头部信息非常重要5.1 BootROM加载TPL/SPL处理流程从可用的存储其中读取ID BLOCK校验ID BLOCK通过, 则加载DDR初始化代码到SRAM中执行5.2 ID BLOCK本质: 给tpl/spl加头部信息通过mkimage工具给tplspl加一个头部信息这个头部信息中包含了魔数, tpl哈希值, spl哈希值, tpl入口地址, spl入口地址等信息make.shmkimage -T rksd -d tpl:spl: idblock.bin / idbloader.img如何管理存储的块信息: uboot/tools/rkcommon.henum { RK_BLK_SIZE 512, RK_SIZE_ALIGN 2048, RK_INIT_OFFSET 4, RK_MAX_BOOT_SIZE 512 10, RK_SPL_HDR_START RK_INIT_OFFSET * RK_BLK_SIZE, RK_SPL_HDR_SIZE 4, };不同芯片版本对应的ID BLOCK不同: uboot/tools/rkcommon.cstruct spl_info { const char *imagename; const char *spl_hdr; const uint32_t spl_size; const bool spl_rc4; const uint32_t header_ver; }; static struct spl_info spl_infos[] { { rk3066, RK30, 0x8000, true, RK_HEADER_V1 }, ... { rk1808, RK18, 0x200000 - 0x2000, false, RK_HEADER_V1 }, ... { rk3568, RK35, 0x10000 - 0x1000, false, RK_HEADER_V2 }, { rk3576, RK35, 0x80000 - 0x1000, false, RK_HEADER_V2 }, { rk3588, RK35, 0x100000 - 0x1000, false, RK_HEADER_V2 }, };不同版本使用的头部数据struct header0_info_v2 { uint32_t magic; // 偏移0x00: RK_MAGIC_V2 0x534E4B52 (RKSN) uint8_t reserved[4]; // 偏移0x04 uint32_t size_and_nimage; // 偏移0x08: [31:16]镜像数; [15:0]hash字段偏移(4B单位) uint32_t boot_flag; // 偏移0x0C: [3:0]hash类型(0none,1sha256,2sha512) uint8_t reserved1[104]; // 偏移0x10 struct image_entry images[4]; // 偏移0x78: 最多4个镜像(TPLSPL) uint8_t reserved2[1064]; uint8_t hash[512]; // header 自身的 SHA256 }; struct image_entry { // rkcommon.c:45-52 uint32_t size_and_off; // [31:16]镜像大小(扇区数); [15:0]镜像扇区偏移 uint32_t address; // 加载地址, 默认 0xFFFFFFFF uint32_t flag; uint32_t counter; // 镜像序号(1,2,...) uint8_t reserved[8]; uint8_t hash[64]; // 该镜像的 hash };ID BLOCK二进制布局存储介质扇区 64 (0x40) 起: ┌─────────────────────────────────────────────────────┐ 0x000 │ header0 (4KB 4扇区) │ │ header0_info_v2 结构 填充 hash[512] │ ← BootROM 先读这里 │ images[0]: TPL — size_and_off[大小|偏移4] │ │ images[1]: SPL — size_and_off[大小|偏移4TPL大小] │ ← BootROM 据此找 SPL ├─────────────────────────────────────────────────────┤ 0x800 (扇区4) │ RK35 (4字节 spl_name) TPL 代码 (init_file) │ ← TPL 数据, 2KB对齐 ├─────────────────────────────────────────────────────┤ 0x800 TPL_size │ SPL 代码 (boot_file) │ ← SPL 数据, 2KB对齐 └─────────────────────────────────────────────────────┘6 SRAMTPL SPL6.1 TPL内存布局: DDR相关, 根据SoC特化配置u-boot-next-dev\arch\arm\mach-rockchip\KconfigRK3568TPL_LDSCRIPT default “arch/arm/mach-rockchip/u-boot-tpl-v8.lds”TPL_TEXT_BASEdefault 0xfdcc1000 - remap[1:0]2’b00: BootRom 0xFFFF0000, SYS_SRAM 0xFDCC0000SRAM是64KB, 从0x1000开始, 说明TPL要小于60KBTPL_MAX_SIZEdefault 61440ROCKCHIP_IRAM_START_ADDR: 0xfdcc0000链接脚本u-boot-next-dev\arch\arm\mach-rockchip\u-boot-tpl-v8.ldsTPL_TEXT_BASE: text - rodata - data - u_boot_list - image_copy_end - bss条件判断CONFIG_TPL_MAX_SIZECONFIG_TPL_BSS_MAX_SIZECONFIG_TPL_MAX_FOOTPRINTCONFIG_TPL_TINY_FRAMEWORK: 极简TPL框架内存布局0xfdcc0000 ┌─────────────────────────────┐ IRAM 基地址 │ BROM 保留区 (0xfdcc0000~0xfdcc1000)│ 含 BROM 启动源ID 0xfdcc0010 0xfdcc1000 ├─────────────────────────────┤ TPL_TEXT_BASE (TPL 加载/运行地址) │ .text (代码段, start.o 在最前) │ │ .rodata (只读数据) │ │ .data (已初始化数据) │ ← TPL_MAX_SIZE60KB 上限 │ .u_boot_list (链表) │ │ .image_copy_end / .end │ 0xfdcc1000 │ .bss (NOLOAD, 运行时清零) │ ← TPL 的 BSS 紧跟在代码后(同一段SRAM) 60KB └─────────────────────────────┘ 0xfdcc1000 0xF000 0xfdcd0000 │ (SRAM 剩余空间留给 BROM 回调) │6.2 SPL内存布局配置include/configs/rk3568_common.h#define CONFIG_SPL_TEXT_BASE 0x00000000 // 行15代码段链接地址(DDR起始)#define CONFIG_SPL_MAX_SIZE 0x00040000 // 行16256KB#define CONFIG_SPL_BSS_START_ADDR 0x03fe0000 // 行17BSS在DDR的0x03fe0000#define CONFIG_SPL_BSS_MAX_SIZE 0x00010000 // 行1864KB#define CONFIG_SPL_STACK 0x03fe0000 // 行19栈在0x03fe0000(与BSS同址)#define CONFIG_SPL_LOAD_FIT_ADDRESS 0x10000000 // 行23FIT临时加载点链接脚本u-boot-next-dev\arch\arm\cpu\armv8\u-boot-spl.lds(ARM64通用SPL脚本)text - rodata - data - u_boot_list - image_copy_end - end -CONFIG_SPL_SKIP_RELOCATE(无重定位) _image_binary_end - bss重定位rel_dyn_start - rela.dyn - .rel_dyn_end - _image_binary_end - bss内存布局DDR 0x00000000 ┌─────────────────────────────┐ .sram 区域 (ORIGINSPL_TEXT_BASE0, LEN256KB) │ .text (代码, start.o 最前) │ ← SPL 被加载到这里运行 │ .rodata │ │ .data │ │ .u_boot_list │ │ .rela.dyn (重定位信息) │ 0x00040000 ├─────────────────────────────┤ SPL_MAX_SIZE 上限 (256KB) │ ... DDR 可用空间 ... │ │ (FIT 镜像临时加载到 0x10000000) │ │ ... │ 0x03fe0000 ├─────────────────────────────┤ .sdram 区域 (ORIGINSPL_BSS_START_ADDR, LEN64KB) │ SPL 栈 (CONFIG_SPL_STACK) │ ← 栈顶 0x03fe0000向下生长 │ ↓ gd 结构 (栈顶预留) │ board_init_f_alloc_reserve 在此预留 gd │ ↓ │ │ .bss (NOLOAD, 64KB) │ ← BSS 段crt0_64.S:144 清零 0x03ff0000 ├─────────────────────────────┤ BSS_MAX_SIZE 上限 │ ... DDR 可用空间 ... │7 DDR内存SPL UBoot Kernel内存物理地址空间32位CPU0x00000000 - 0xEFFFFFFF3.75G内存0xF0000000 - 0xFFFFFFFF外设寄存器64位CPU0x00000000 - 0xEFFFFFFF3.75G内存0xF0000000 - 0xFFFFFFFF外设寄存器超过4G的位置依然可以随意访问也就是说DDR可以扩展到8G16G设置更多对于ARM64来说支持48位的扩展地址7.1 DDR内存地址布局uboot/include/configs/rk3568_common.hSPLCONFIG_SPL_TEXT_BASE0x00000000CONFIG_SPL_MAX_SIZE0x40000限制256KB。对应 MiniLoaderAll.bin 的代码容量上限CONFIG_SPL_STACK0x03fe0000SPL 运行栈地址CONFIG_SPL_BSS_START_ADDR0x03fe0000SPL BSS 段起始地址CONFIG_SPL_BSS_MAX_SIZE0x1000064KB。SPL 全局变量BSS 段最大空间CONFIG_SPL_LOAD_FIT_ADDRESS0x10000000SPL 加载 FIT 镜像 (u-boot.itb) 的内存目标地址UBootCONFIG_SYS_TEXT_BASEU-Boot 主程序运行基地址。正常启动U-Boot 加载至 0x00a00000 运行USB烧录调试模式重定位到 0x00000000。CONFIG_SYS_INIT_SP_ADDRU-Boot 启动初期栈指针地址CONFIG_SYS_LOAD_ADDR默认下载地址loadb/loadx 等命令默认把文件读到这个内存地址CONFIG_SYS_SDRAM_BASE0。DDR内存基地址为0SDRAM_MAX_SIZE0xf0000000。可用DDR上限上方保留给外设寄存器Kernel#define ENV_MEM_LAYOUT_SETTINGS \ scriptaddr0x00c00000\0 \ pxefile_addr_r0x00e00000\0 \ fdt_addr_r0x08300000\0 \ kernel_addr_r0x00280000\0 \ kernel_addr_c0x04080000\0 \ ramdisk_addr_r0x0a200000\07.2 DDR内存地址布局来源于uboot手册【DDR内存地址布局】 ATF Start Addr:0x00000000 Size:1M Usage:ARM Trusted Firmware Secure:Yes SHM Start Addr:0x00100000 Size:1M Usage:SHM, Pstore Secure:No OP-TEE Start Addr:0x08400000 Size:2M~30M Usage:参考TEE开发手册 Secure:Yes FDT Start Addr:fdt_addr_r Size:- Usage:kernel dtb Secure:No KERNEL Start Addr:kernel_addr_r Size:- Usage:kernel镜像 Secure:No RAMDISK Start Addr:ramdisk_addr_r Size:- Usage:ramdisk镜像 Secure:No …… Start Addr:- Size:- Usage:- Secure:- FASTBOOT Start Addr:- Size:- Usage:Fastboot buffer Secure:No …… Start Addr:- Size:- Usage:- Secure:- SP Start Addr:- Size:- Usage:stack Secure:No FDT Start Addr:- Size:sizeof(dtb) Usage:U-Boot dtb Secure:No GD Start Addr:- Size:sizeof(gd) Usage:- Secure:No Board Start Addr:- Size:sizeof(bd_t) Usage:- Secure:No MALLOC Start Addr:- Size:CONFIG_SYS_MALLOC_LEN Usage:系统的堆空间 Secure:No U-Boot Start Addr:- Size:sizeof(mon) Usage:u-boot镜像 Secure:No Video FB Start Addr:- Size:fb size(32M) Usage:显示帧缓存 Secure:No TLB Table Start Addr:RAM_TOP-64K Size:32K Usage:MMU页表 Secure:No 【PS】 64位平台: ATF是ARMv8必需的, OP-TEE是可选的; 32位平台, 只有OP-TEE kernel fdt/kernel/ramdisk是U-Boot需要加载的固件地址, 由ENV_MEM_LAYOUT_SETTINGS定义 Fastboot功能需要的buffer地址和大小在deconfig中定义 OP-TEE 占据的空间需要根据实际需求而定7.3 SPL加载UBootSPL加载FIT镜像: uboot.itb配置: CONFIG_ROCKCHIP_FIT_IMAGE_PACKFIT 本质是 FDT设备树格式blobmagic FDT_MAGIC0xd00dfeedFIT 由 make_fit_atf.sh 生成 u-boot.its再 mkimage -f u-boot.its -E uboot.itb-E 外部数据打包。结构arch/arm/mach-rockchip/fit_nodes.shFIT打包FIT 包含的关键信息属性定义在 include/image.h:923-953 - loadFIT_LOAD_PROP镜像加载地址 - entryFIT_ENTRY_PROP镜像入口地址uboot 节点无此属性 - osFIT_OS_PROPOS 类型——arm-trusted-firmware/U-Boot/op-teeSPL 据此决定跳转方式 - data/data-position/data-offset/data-size镜像数据-E 外部数据 - hash每段 SHA256SPL 校验完整性 - firmware/loadables/fdt配置节点指定加载顺序从启动到FI镜像加载SPL 入口 start.S:21 _start → reset → save_boot_paramssetjmp 保存 BROM 上下文→ 设 EL3 → master_cpu: bl _mainstart.S:237→ crt0_64.S:68 _main - crt0_64.S:75-76ldr x0, (CONFIG_SPL_STACK0x03fe0000) 设栈 - crt0_64.S:82-86board_init_f_alloc_reserve/board_init_f_init_reserve栈顶预留 gd - crt0_64.S:89bl board_init_fspl.c:204—— spl_early_init、RAM init、console - crt0_64.S:125-138spl_relocate_stack_gdRK3568 返回0不重定位栈 - crt0_64.S:144-149清 BSS0x03fe0000~0x03ff0000 - crt0_64.S:152-154b board_init_rcommon/spl/spl.c:507。 board_init_rspl.c:507-650SPL 主循环 - spl.c:560-561entry_point_bl32-1; entry_point_bl33CONFIG_SYS_TEXT_BASE默认值 - spl.c:573board_boot_order → spl_boot_device返回 BOOT_DEVICE_MMC1 - spl.c:575boot_from_devices → spl_mmc_load_imagespl_mmc.c:282。加载FIT流程① 检测 FITspl_mmc.c:57-105 mmc_load_image_raw_sector header (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); blk_dread(..., sector, 1, header); // 读1扇区头部 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) image_get_magic(header) FDT_MAGIC) // line 76-82 ★ spl_load_simple_fit(spl_image, load, sector, header); // line 91 → FIT 路径 ② 加载 FIT blob 到内存spl_fit.c:929 spl_load_simple_fit → spl_fit.c:702 spl_internal_load_simple_fit - spl_fit_load_blobspl_fit.c:489-538把整个 FIT DTB 放在 CONFIG_SYS_TEXT_BASE - size 之前≈0x009fxxxxbase_offset 供外部>镜像加载地址┌───────────────┬───────────┬──────────────────────────────┬─────────────────────────┬────────────────────────────────────────────────────┐ │ 镜像 │ FIT 节点 │ 加载地址 │ 地址来源 │ 文件:行号 │ ├───────────────┼───────────┼──────────────────────────────┼─────────────────────────┼────────────────────────────────────────────────────┤ │ U-Boot │ uboot │ 0x00a00000 │ CONFIG_SYS_TEXT_BASE │ rk3568_common.h:32; fit_args.sh:120; spl_fit.c:888 │ ├───────────────┼───────────┼──────────────────────────────┼─────────────────────────┼────────────────────────────────────────────────────┤ │ ATF bl31 段1 │ atf-1 │ bl31.elf 段1 p_paddr │ decode_bl31.py:31 │ fit_nodes.sh:129; spl_fit.c:837 │ ├───────────────┼───────────┼──────────────────────────────┼─────────────────────────┼────────────────────────────────────────────────────┤ │ ATF bl31 段2 │ atf-2.. │ 各段 p_paddr │ 同上 │ fit_nodes.sh:166 │ ├───────────────┼───────────┼──────────────────────────────┼─────────────────────────┼────────────────────────────────────────────────────┤ │ OP-TEE │ optee │ 0x08400000 │ DRAM_BASE(0)0x08400000 │ fit_args.sh:44; spl_fit.c:914 │ ├───────────────┼───────────┼──────────────────────────────┼─────────────────────────┼────────────────────────────────────────────────────┤ │ U-Boot dtb │ fdt │ 紧跟 firmware 之后 │ spl_fit_append_fdt │ spl_fit.c:417 │ ├───────────────┼───────────┼──────────────────────────────┼─────────────────────────┼────────────────────────────────────────────────────┤ │ FIT 临时 DTB │ 整个 blob │ 0x009fxxxxTEXT_BASE 之前 │ spl_fit_load_blob │ spl_fit.c:525 │ └───────────────┴───────────┴──────────────────────────────┴─────────────────────────┴────────────────────────────────────────────────────┘镜像调用spl_fit.c:888spl_image-entry_point_bl33 image_info.load_addr 0x00a00000。 跳转分发spl.c:590-604 switch (spl_image.os) { case IH_OS_ARM_TRUSTED_FIRMWARE: // line 596 printf(Jumping to %s(0x%08lx) via ARM Trusted Firmware(0x%08lx)\n, ..., (ulong)spl_image.entry_point_bl33, (ulong)spl_image.entry_point); spl_invoke_atf(spl_image); // line 602 ★ break; } 跳转前的准备工作 ① 从 FDT /fit-images 查找最终入口spl_atf.c:171-220 spl_invoke_atf ② 清理spl_atf.c:212 spl_cleanup_before_jump定义在 spl.c:725-757 ③ 构造 bl31_params 并跳转spl_atf.c:123-133 bl31_entry 跳转后ATF(bl31) 在 EL3 初始化安全世界 → 启动 OP-TEEEL1 Secure → ERET 到 U-BootEL2 Non-secure0x00a00000。 为什么 SPL 不直接跳 U-Boot 而要先跳 ATF 1. EL 切换必须经 ERETSPL 在 EL3 SecureU-Boot 要在 EL2 Non-secure从 EL3 降到 EL2 同时切安全态只能靠 ERET目标 EL 由 SPSR_EL3/ELR_EL3 决定SPL 直接跳做不到 2. 常驻 EL3 服务kernel 运行后需要 PSCI多核上下电、SMC 路由访问 OP-TEE/加密/OTP没有 bl31 常驻 EL3kernel 发 SMC 无人响应 3. Secure/Normal 世界分离OP-TEE 需先在 EL1 Secure 启动ATF 负责调度 BL31→BL32→BL33。7.4 UBoot加载KernelKernel镜像格式Android boot.img: uboot/include/android_image.huboot/common/image-android.c镜像布局header(1页) | kernel(n) | ramdisk(m) | second(o) | [dtb]ARM64 Image headerDocumentation/arm64/booting.txt in the Linux kerneluboot/cmd/booti.c:20-31RK私有镜像bootrkp.c8 字节 headertagTAG_KERNEL size data CRC32FIT镜像FDT 格式内含 kernel/ramdisk/fdt 子节点fit_get_blobfit.c:139-215从 boot/recovery 分区读取镜像处理路径┌──────────────┬────────────────┬────────────────────┬────────────────────────┬──────────────────────────────────────────────────┐ │ 路径 │ 命令 │ Kernel 来源 │ 镜像格式 │ 文件:行号 │ ├──────────────┼────────────────┼────────────────────┼────────────────────────┼──────────────────────────────────────────────────┤ │ bootrkp │ bootrkp │ kernel 分区 │ RK 私有 rockchip_image │ cmd/bootrkp.c:215-300 │ ├──────────────┼────────────────┼────────────────────┼────────────────────────┼──────────────────────────────────────────────────┤ │ boot_android │ boot_android │ boot/recovery 分区 │ Android boot.img │ cmd/boot_android.c:21; android_bootloader.c:1217 │ ├──────────────┼────────────────┼────────────────────┼────────────────────────┼──────────────────────────────────────────────────┤ │ boot_fit │ boot_fit │ boot/recovery 分区 │ FIT │ cmd/bootfit.c:59; fit.c:422 │ ├──────────────┼────────────────┼────────────────────┼────────────────────────┼──────────────────────────────────────────────────┤ │ distro │ distro_bootcmd │ 任意设备 │ extlinux.conf/boot.scr │ config_distro_bootcmd.h:383 │ └──────────────┴────────────────┴────────────────────┴────────────────────────┴──────────────────────────────────────────────────┘进入uboot, 倒计时无按键则执行bootcmd按顺序执行#define RKIMG_BOOTCOMMAND \ boot_android ${devtype} ${devnum}; \ boot_fit; \ bootrkp; \ run distro_bootcmd;加载位置#define ENV_MEM_LAYOUT_SETTINGS \ scriptaddr0x00c00000\0 \ pxefile_addr_r0x00e00000\0 \ fdt_addr_r0x08300000\0 \ kernel_addr_r0x00280000\0 \ kernel_addr_c0x04080000\0 \ ramdisk_addr_r0x0a200000\0