news 2026/9/20 10:37:02

[Linux外设驱动详解]RK3588 U-Boot 启动流程详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[Linux外设驱动详解]RK3588 U-Boot 启动流程详解

RK3588 U-Boot 启动流程详解

目录

  1. 概述
  2. 硬件架构
  3. 启动阶段划分
  4. SPL 阶段详解
  5. U-Boot 阶段详解
  6. 关键数据结构
  7. 时序图
  8. 源码路径参考

概述

RK3588 是瑞芯微(Rockchip)推出的旗舰级 ARM64 SoC,采用 4xCortex-A76 + 4xCortex-A55 大小核架构。本文档详细分析 RK3588 平台上 U-Boot 的完整启动流程。

启动镜像组成

┌─────────────────────────────────────────────────────────┐ │ RK3588 启动镜像 │ ├─────────────────────────────────────────────────────────┤ │ BootROM (芯片内部固件) │ │ ├─ 检测启动设备 │ │ └─ 加载 SPL(TPL) │ ├─────────────────────────────────────────────────────────┤ │ SPL (Secondary Program Loader) │ │ ├─ 初始化 DDR │ │ ├─ 初始化串口 │ │ ├─ 加载 ATF/OPTEE │ │ └─ 加载 U-Boot │ ├─────────────────────────────────────────────────────────┤ │ ATF (ARM Trusted Firmware) │ │ ├─ EL3 安全监控 │ │ └─ PSCI 电源管理 │ ├─────────────────────────────────────────────────────────┤ │ OPTEE (可选的安全OS) │ │ └─ Secure World 服务 │ ├─────────────────────────────────────────────────────────┤ │ U-Boot (主程序) │ │ └─ 最终引导操作系统 │ └─────────────────────────────────────────────────────────┘

硬件架构

RK3588 核心规格

项目规格
CPU4x Cortex-A76 @ 2.4GHz + 4x Cortex-A55 @ 1.8GHz
GPUMali-G610 MP4
NPU6TOPS RKNN
VPU8K VP9 + 8K H265 + 4K AV1 解码
内存支持 LPDDR4/LPDDR4X/LPDDR5
启动设备eMMC 5.1、SD卡 3.01、SPI NAND、SPI NOR

内存映射

// 源码: arch/arm/mach-rockchip/rk3588/rk3588.c:108-142staticstructmm_regionrk3588_mem_map[]={{.virt=0x0UL,// 0GB.phys=0x0UL,.size=0xf0000000UL,// ~3.75GB (普通内存).attrs=PTE_BLOCK_MEMTYPE(MT_NORMAL)|PTE_BLOCK_INNER_SHARE},{.virt=0xf0000000UL,// ~3.75GB.phys=0xf0000000UL,.size=0x10000000UL,// 256MB (设备寄存器).attrs=PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE)|PTE_BLOCK_NON_SHARE},{.virt=0x100000000UL,// 4GB.phys=0x100000000UL,.size=0x700000000UL,// ~28GB (高地址内存).attrs=PTE_BLOCK_MEMTYPE(MT_NORMAL)|PTE_BLOCK_INNER_SHARE},{.virt=0x900000000,// ~36GB.phys=0x900000000,.size=0x150000000,// ~5.25GB (PCIe设备).attrs=PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE)|PTE_BLOCK_NON_SHARE}};

启动阶段划分

┌────────────────────────────────────────────────────────────────────┐ │ RK3588 完整启动流程 │ └────────────────────────────────────────────────────────────────────┘ 上电/复位 │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 阶段1: BootROM (芯片内部ROM) │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. 从 BootROM 启动 │ │ │ │ 2. 检测启动设备 (eMMC/SD卡/SPI Flash) │ │ │ │ 3. 加载 IDBlock (SPL/TPL) 到 SRAM │ │ │ │ 4. 验证签名 (如果启用安全启动) │ │ │ │ 5. 跳转到 SPL 入口地址 │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 阶段2: SPL (Secondary Program Loader) │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 2.1 start.S (armv8/start.S) │ │ │ │ └─ CPU 初始化、异常向量表设置 │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 2.2 lowlevel_init() │ │ │ │ ├─ 使能 I-Cache │ │ │ │ └─ 初始化 GIC (中断控制器) │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 2.3 _main() → board_init_f() │ │ │ │ ├─ rockchip_stimer_init() // 系统计器初始化 │ │ │ │ ├─ debug_uart_init() // 串口初始化 │ │ │ │ ├─ spl_early_init() // DM框架、设备树 │ │ │ │ ├─ dram_init() // DDR初始化 │ │ │ │ ├─ arch_cpu_init() // CPU架构初始化 │ │ │ │ └─ preloader_console_init() // 控制台初始化 │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 2.4 board_init_r() │ │ │ │ ├─ spl_board_init() // 板级初始化 │ │ │ │ ├─ 确定启动设备 (board_boot_order) │ │ │ │ ├─ 加载 FIT 镜像 │ │ │ │ ├─ 解析 ATF/OPTEE/U-Boot │ │ │ │ └─ 准备跳转 │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 2.5 jump_to_image_no_args() │ │ │ │ └─ 跳转到 ATF (BL31) │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 阶段3: ATF (ARM Trusted Firmware - BL31) │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. EL3 初始化 │ │ │ │ 2. 初始化安全监控器 (Secure Monitor) │ │ │ │ 3. 加载 OPTEE (BL32) - 可选 │ │ │ │ 4. 设置 PSCI 接口 │ │ │ │ 5. 降级到 EL2 并跳转到 U-Boot (BL33) │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 阶段4: U-Boot Proper │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 4.1 start.S (armv8/start.S) │ │ │ │ └─ 同 SPL 启动流程 │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 4.2 board_init_f() │ │ │ │ ├─ 硬件初始化 │ │ │ │ ├─ 设备模型初始化 │ │ │ │ └─ 环境变量设置 │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 4.3 board_init_r() │ │ │ │ ├─ 网络初始化 │ │ │ │ ├─ 存储设备初始化 │ │ │ │ ├─ 显示初始化 │ │ │ │ └─ 进入主循环 │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 4.4 main_loop() │ │ │ │ ├─ 启动延迟 │ │ │ │ ├─ 命令处理 │ │ │ │ └─ 执行 bootcmd │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ │ ▼ 操作系统内核 (Kernel)

SPL 阶段详解

1. 入口: start.S

文件位置: arch/arm/cpu/armv8/start.S:20-238

// reset 向量 - 上电后首先执行 reset: b save_boot_params // 保存启动参数 // 根据当前异常级别(EL)设置异常向量表 switch_el x1, 3f, 2f, 1f 3: msr vbar_el3, x0 // EL3: 设置异常向量 orr x0, x0, #0xf // SCR_EL3.NS|IRQ|FIQ|EA msr scr_el3, x0 b 0f 2: msr vbar_el2, x0 // EL2 b 0f 1: msr vbar_el1, x0 // EL1 0: // 使能 I-Cache mov x1, #CR_I switch_el x2, 3f, 2f, 1f 3: mrs x0, sctlr_el3 orr x0, x0, x1 msr sctlr_el3, x0 // 调用底层初始化 bl lowlevel_init // 跳转到 C 代码 master_cpu: bl _main

关键点:

  • _start是链接脚本定义的入口点
  • 支持 EL1/EL2/EL3 不同的异常级别
  • 设置异常向量表vbar_elx
  • 使能指令缓存

2. lowlevel_init

文件位置: arch/arm/cpu/armv8/start.S:336-390

WEAK(lowlevel_init)mov x29,lr/* 保存返回地址 */#ifCONFIG_IS_ENABLED(IRQ)branch_if_slave x0,1fldr x0,=GICD_BASE bl gic_init_secure// 初始化 GIC 分发器1:#ifdefined(CONFIG_GICV3)ldr x0,=GICR_BASE bl gic_init_secure_percpu// 初始化 GIC CPU 接口#endif#endifmov lr,x29/* 恢复返回地址 */retENDPROC(lowlevel_init)

3. board_init_f - SPL初始化核心

文件位置: arch/arm/mach-rockchip/spl.c:189-251

voidboard_init_f(ulong dummy){gd->flags=dummy;// 1. 系统计器初始化rockchip_stimer_init();// 2. 调试串口初始化if(!gd->serial.using_pre_serial&&!(gd->flags&GD_FLG_DISABLE_CONSOLE))debug_uart_init();printascii("U-Boot SPL board init");gd->sys_start_tick=get_ticks();// 记录启动时间// 3. DM 框架早期初始化ret=spl_early_init();if(ret){printf("spl_early_init() failed: %d\n",ret);hang();}// 4. DDR 初始化 (关键!)debug("\nspl:init dram\n");ret=uclass_get_device(UCLASS_RAM,0,&dev);if(ret){printf("DRAM init failed: %d\n",ret);return;}// 5. 控制台初始化preloader_console_init();// 6. 热键检测 (如 Ctrl+B 触发下载模式)spl_hotkey_init();// 7. 架构相关初始化
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 17:52:30

Windows 11 LTSC缺失微软商店?技术深度解析与完整解决方案

Windows 11 LTSC缺失微软商店?技术深度解析与完整解决方案 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore Windows 11 LTSC系统以其稳定性…

作者头像 李华
网站建设 2026/9/19 6:15:53

frpc-desktop智能连接守护技术:构建永不中断的内网穿透通道

在远程办公和智能家居日益普及的今天,内网穿透技术已成为连接内外网络的关键桥梁。然而,传统frp工具在面对网络波动、路由器策略限制等复杂环境时,频繁的连接中断严重影响了用户体验。frpc-desktop通过创新的智能连接守护机制,成功…

作者头像 李华
网站建设 2026/9/17 23:36:55

利用PaddlePaddle镜像快速实现工业级目标检测(PaddleDetection)

利用PaddlePaddle镜像快速实现工业级目标检测 在智能制造产线日益智能化的今天,一个常见的挑战是:如何在短短几天内完成从数据标注到模型上线的全流程?许多团队曾因环境配置冲突、依赖版本不匹配或部署链路断裂而延误项目进度。尤其是在边缘设…

作者头像 李华
网站建设 2026/9/3 16:15:55

【C++】面试官爱的C++多态八股文,这次让你彻底搞懂!

问题引入:这篇文章重点介绍C中的多态特性。前面我们知道了,派生类中可以调用基类中的方法,对于同名的函数我们有隐藏的相关概念。但是现实可能存在一个问题,就是基类中的方法和派生类中的方法是不同的,不同的对象调用的…

作者头像 李华
网站建设 2026/9/10 1:37:09

PaddleDetection实战:用PaddlePaddle镜像完成YOLOv3目标检测

PaddleDetection实战:用PaddlePaddle镜像完成YOLOv3目标检测 在智能安防、无人零售和工业质检等现实场景中,开发者常常面临一个共性难题:如何在有限时间内快速搭建一个稳定、高效的目标检测系统?传统方式往往需要花费大量精力配置…

作者头像 李华
网站建设 2026/9/16 13:22:00

终极跨平台模组下载神器:WorkshopDL完整使用指南

终极跨平台模组下载神器:WorkshopDL完整使用指南 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 问题发现:非Steam玩家的模组困境 你是否曾经在Epic Ga…

作者头像 李华