ATF (ARM Trusted Firmware) -3:完整启动流程(热启动)

ATF 热启动(Warm Boot)全流程

热启动(Warm Reset)是指系统已完成冷启动并运行后,通过软件或硬件触发的复位流程。与冷启动相比,热启动的核心特点是保留 DRAM 内容,跳过耗时的 DRAM 初始化(训练),从而大幅缩短启动时间。

DRAM 训练(也叫 DDR 训练),是DDR 内存控制器在冷启动初始化阶段,通过一系列硬件校准算法,动态调整内存信号的时序、相位、电压、驱动强度等关键参数,确保 CPU 与 DRAM 颗粒之间的高速并行数据传输稳定、无错的硬件校准过程。


一、热启动概述

1. 与冷启动的核心差异

维度 冷启动(Cold Boot) 热启动(Warm Boot)
触发条件 系统上电、硬复位 软件触发(PSCI)、看门狗复位、软复位按钮
DRAM 状态 未初始化,需完整训练(Training) 已初始化,内容保留,跳过训练
镜像加载 从 Flash 重新加载 BL1/BL2/BL31/BL32/BL33 可选:若内存内容保留,可跳过部分镜像重加载
启动时间 长(需 DRAM 训练) 短(跳过 DRAM 训练)

2. 常见触发方式

  • 软件触发
    • Linux/Android 通过 PSCI(Power State Coordination Interface)调用 SYSTEM_RESETSYSTEM_RESET2
    • 直接写平台的复位控制寄存器
  • 硬件触发
    • 看门狗定时器超时(Watchdog Reset)
    • 软复位按钮(保留 DRAM 电源)
    • 调试器触发复位

二、ATF 热启动全流程

ATF 热启动仍遵循"BL1 → BL2 → BL31 → BL32/BL33"的基本链路,但在各阶段会根据复位原因跳过冗余步骤。


第一阶段:复位触发与 BL1 处理

1.1 复位入口

系统复位后,CPU 强制进入 EL3(AArch64)Secure Monitor Mode(AArch32) ,从 BL1 ROM 的固定入口地址开始执行(与冷启动一致)。

1.2 BL1 核心逻辑

BL1 会先完成最小化硬件初始化 (如关中断、初始化 SRAM、UART),然后通过平台复位状态寄存器判断复位原因(冷启动/热启动)。

核心代码(BL1)
  • 文件bl1\bl1_main.c

  • 关键函数bl1_main()

    c 复制代码
    void bl1_main(void) {
       unsigned int image_id; // 存储下一个要加载的镜像ID
    
      	/* 如果启用EARLY_CONSOLE标志,则启用早期控制台 */
      	plat_setup_early_console();
      
      	/* 执行早期平台特定设置 */
      	bl1_early_platform_setup();
      
      	/* 执行晚期平台特定设置 */
      	bl1_plat_arch_setup();
    
        // 2. 获取复位原因(平台相关代码)
        uint32_t reset_status = bl1_plat_get_reset_status();
    
        // 3. 若为热启动,可选择跳过部分 BL1 初始化(平台自定义)
        if (reset_status == WARM_RESET) {
            // 可选:跳过某些非必要初始化
        }
    
        // 4. 加载并验签 BL2(与冷启动一致,热启动通常仍需走 BL2)
        bl1_load_bl2();
    
        // 5. 准备跳转参数,跳转到 BL2
        bl1_prepare_next_image();
    }
  • 复位原因检测(平台相关)

    • 文件plat/<厂商>/<平台>/<平台>_pm.c(如 plat/arm/board/fvp/fvp_pm.c

    • 关键函数bl1_plat_get_reset_status()plat_get_reset_status()

      c 复制代码
      // 示例:FVP 平台获取复位状态
      uint32_t fvp_get_reset_status(void) {
          return mmio_read_32(FVP_RESET_STATUS_REG) & FVP_WARM_RESET_FLAG;
      }

第二阶段:BL2 处理(热启动核心优化点)

BL2 是热启动优化的核心阶段 ------热启动时 DRAM 已初始化且内容保留,BL2 会跳过 DRAM 训练(Training),仅需验证/加载后续镜像(或直接使用内存中已有的镜像)。

2.1 BL2 核心逻辑
  1. 基础初始化:初始化 UART、存储控制器(若需从 Flash 读镜像)。
  2. DRAM 状态检测:通过平台寄存器或内存魔数(Magic Number)判断 DRAM 是否已初始化。
  3. 跳过 DRAM 初始化:若为热启动,直接使用现有 DRAM,不执行耗时的训练流程。
  4. 镜像处理
    • 若内存中 BL31/BL32/BL33 镜像完整(通过校验和/魔数验证),则跳过从 Flash 重加载
    • 否则,仍需从 Flash 重新加载并验签。
  5. 准备跳转参数:将 BL31/BL32/BL33 的入口地址传递给 BL31。
  6. 跳转到 BL31
核心代码(BL2)
  • 文件bl2/bl2_main.c

  • 关键函数bl2_main()

    c 复制代码
    void bl2_main(void) {
        // 1. 基础初始化
        bl2_early_platform_setup2();
        bl2_plat_arch_setup();
    
        // 2. 检测 DRAM 状态(平台相关)
        bool dram_is_ready = bl2_plat_is_dram_ready();
    
        // 3. 仅冷启动时初始化 DRAM
        if (!dram_is_ready) {
            // 执行 DRAM 训练(耗时步骤,热启动跳过)
            bl2_plat_dram_init();
        }
    
        // 4. 加载/验签 BL31/BL32/BL33(热启动可优化为跳过)
        bl2_load_images();
    
        // 5. 准备跳转参数,跳转到 BL31
        bl2_prepare_next_image();
    }
  • DRAM 状态检测(平台相关)

    • 文件plat/<厂商>/<平台>/<平台>_bl2_setup.c

    • 关键函数bl2_plat_is_dram_ready()

      c 复制代码
      // 示例:通过内存魔数判断 DRAM 是否保留
      #define DRAM_MAGIC 0x12345678
      bool bl2_plat_is_dram_ready(void) {
          // 检查 DRAM 特定地址的魔数是否匹配
          return mmio_read_32(DRAM_MAGIC_ADDR) == DRAM_MAGIC;
      }

第三阶段:BL31 处理(热启动与 PSCI 联动)

BL31 是热启动的控制枢纽,负责:

  1. 初始化 EL3 运行时环境;
  2. 处理 PSCI 热启动请求(如 CPU_ONSYSTEM_RESET);
  3. 协调安全世界(OP-TEE)与非安全世界(Linux/Android)的状态恢复。
3.1 BL31 核心逻辑
  1. EL3 基础初始化:初始化栈、异常向量表、GIC 中断控制器。
  2. PSCI 服务初始化:注册 PSCI 处理函数,支持热启动相关的标准接口。
  3. 安全世界状态处理
    • 若 OP-TEE(BL32)仍在内存中,可跳过 OP-TEE 重初始化,直接恢复其上下文;
    • 否则,仍需跳转到 OP-TEE 重新初始化。
  4. 切换到非安全世界 :配置非安全世界上下文,通过 ERET 跳转到 BL33(LK/U-Boot)。
3.2 PSCI 热启动关键接口

PSCI 是软件触发热启动的标准接口,Linux/Android 通过 SMC 调用以下 PSCI 函数:

  • PSCI_VERSION:获取 PSCI 版本;
  • SYSTEM_RESET/SYSTEM_RESET2:触发系统热复位;
  • CPU_ON:热启动指定的 CPU 核心(多核系统)。
核心代码(BL31 与 PSCI)
  • PSCI 系统复位处理

    • 文件lib\psci\psci_system_off.c
    • 关键函数psci_system_reset()
  • PSCI CPU 热启动处理

    • 文件lib\psci\psci_on.c

    • 关键函数psci_cpu_on_start()

      c 复制代码
      int psci_cpu_on_start(u_register_t target_cpu, u_register_t entry_point) {
          // 1. 验证目标 CPU 状态
          if (!psci_is_valid_cpu(target_cpu)) return PSCI_E_INVALID_PARAMS;
      
          // 2. 配置目标 CPU 的入口地址
          psci_set_cpu_entry_point(target_cpu, entry_point);
      
          // 3. 平台相关:唤醒目标 CPU
          plat_psci_cpu_on(target_cpu);
      
          return PSCI_E_SUCCESS;
      }
  • BL31 主流程

    • 文件bl31/bl31_main.c

    • 关键函数bl31_main()

      c 复制代码
      void bl31_main(void) {
          // 1. EL3 基础初始化
          bl31_early_platform_setup2();
          bl31_plat_arch_setup();
      
          // 2. 初始化运行时服务(包括 PSCI)
          runtime_svc_init();
      
          // 3. 准备下一个镜像(BL32 或 BL33)
          entry_point_info_t *next_image = bl31_plat_get_next_image_ep_info(SECURE);
          if (!next_image) {
              next_image = bl31_plat_get_next_image_ep_info(NON_SECURE);
          }
      
          // 4. 跳转到下一个镜像
          el3_exit(next_image);
      }

第四阶段:BL32(OP-TEE)与 BL33(非安全世界)处理

4.1 BL32(OP-TEE)
  • 若为热启动且 OP-TEE 内存保留,BL31 可直接恢复 OP-TEE 上下文,跳过其完整初始化;
  • 否则,仍需跳转到 OP-TEE 执行 init_tee_runtime()(与冷启动一致)。
4.2 BL33(LK/U-Boot)与 Linux
  • BL33 会检测热启动状态,跳过部分外设初始化;
  • Linux 内核启动后,通过 /proc/cmdline 或平台寄存器识别热启动,跳过某些驱动的重初始化,快速恢复用户空间。

三、热启动特殊路径:RESET_TO_BL31

部分平台支持 RESET_TO_BL31=1 编译配置,热启动时可跳过 BL1/BL2,直接从 BL31 入口启动,进一步缩短启动时间。

核心逻辑

  1. 系统复位后,CPU 直接跳转到 BL31 的加载地址(而非 BL1 ROM);
  2. BL31 检测复位原因,若为热启动,跳过 BL1/BL2 处理,直接初始化 EL3 并切换到非安全世界。

核心代码

通过链接脚本直接进行跳转

执行bl31热启动流程

四、总结:热启动核心优化点

  1. DRAM 初始化:热启动跳过 DRAM 训练(最大的时间优化);
  2. 镜像加载:若内存内容保留,可跳过从 Flash 重加载 BL31/BL32/BL33;
  3. 安全世界:OP-TEE 可直接恢复上下文,跳过完整初始化;
  4. 路径简化 :支持 RESET_TO_BL31,跳过 BL1/BL2。

通过以上优化,热启动时间通常可从冷启动的数秒缩短至数百毫秒甚至更短。

相关推荐
哈哈浩丶2 小时前
OP-TEE-OS:综述
android·linux·驱动开发
哈哈浩丶2 小时前
ATF (ARM Trusted Firmware) -1:综述
linux·arm开发·驱动开发
小李独爱秋2 小时前
模拟面试:lvs常见的工作模式有哪些?各有什么特点?
linux·运维·面试·职场和发展·操作系统·职场发展·lvs
恋猫de小郭11 小时前
你是不是觉得 R8 很讨厌,但 Android 为什么选择 R8 ?也许你对 R8 还不够了解
android·前端·flutter
Codefengfeng11 小时前
分辨压缩包的真加密与伪加密
linux·运维·网络
暴力求解12 小时前
Linux---进程(五)进程调度
linux·运维·服务器
楼田莉子12 小时前
C++项目:日志&&线程池
linux·c++·学习·visual studio code
wsad053212 小时前
Linux 用户和组管理完整指南(中英文参数对照)
linux·运维·服务器
S-码农12 小时前
Linux进程通讯——共享内存
linux