4. S32G启动流程与虚拟化环境搭建
S32G 的启动不是“上电后直接跑 Linux”这么简单,而是一条由硬件信任根逐级向软件世界传递控制权的链。理解这条链,是搭建虚拟化环境的前提:只有知道每一级镜像由谁校验、被放到哪里、以什么异常等级运行,才能在 Hypervisor 启动失败时快速定位是 HSE 固件没起来、ATF 没切到 EL2,还是 U-Boot 的设备树把 CPU 释放错了。
一、启动链的五个阶段与信任传递
S32G 上电后,CPU 首先执行片内 BootROM。BootROM 读取启动模式引脚(如从 QSPI、SD、eMMC 启动),从对应介质加载第一级镜像,并用芯片内固化的密钥或 HSE 提供的服务校验其签名。校验通过后,控制权交给 HSE 固件与引导加载程序。HSE(Hardware Security Engine)固件运行在独立的安全核上,负责密钥管理、加解密、安全启动校验和生命周期管理,它先于应用核的软件就绪,后续每一级镜像的验签都可以请求 HSE 完成。
应用核侧的顺序通常是:BootROM → HSE 固件 → BL2(ATF 的第一阶段)→ BL31(ATF 运行时)→ U-Boot → Hypervisor → Guest OS。其中 ATF(Arm Trusted Firmware)承担异常等级切换与 PSCI 服务:BL2 在 EL3 完成平台初始化并加载 BL31、BL33(即 U-Boot),BL31 常驻 EL3,提供电源管理、CPU 上下电和系统复位等 SMC 调用。U-Boot 运行在 EL2 或 EL1,负责加载 Hypervisor 镜像与各 Guest 的内核、设备树,最后通过 booti/bootm 跳转。Hypervisor 接管 EL2 后创建虚拟机,把 Guest 内核放到 EL1 运行。
二、镜像布局与加载地址
在 S32G 的典型工程中,各镜像按固定偏移写入启动介质。以 QSPI 启动为例,BootROM 从 0x0 读取头部并加载 HSE 固件与 BL2;BL2 依据镜像头中的加载地址把 BL31 放到 SRAM 或 DDR 的保留区,把 U-Boot 放到 DDR 的代码段。U-Boot 再从存储或网络加载 Hypervisor 与 Guest 镜像。下面是一份示例性的镜像布局,实际地址需以所用 BSP 的链接脚本和启动头为准:
QSPI 偏移 镜像 目标地址 说明
0x0000_0000 BootROM 头/BL2 片内 SRAM BootROM 直接加载
0x0001_0000 HSE 固件 安全核专用区 由 BootROM 校验后启动
0x0004_0000 BL31 (ATF) DDR 保留区 EL3 运行时
0x0010_0000 U-Boot (BL33) DDR 代码段 EL2/EL1 引导
0x0080_0000 Hypervisor DDR 高地址 EL2 接管
0x0100_0000 Guest0 内核+DTB DDR 低地址 EL1 运行
0x0180_0000 Guest1 内核+DTB DDR 中地址 EL1 运行
需要强调的是,BL31 必须放在所有 Guest 都不会覆盖的区域,因为它是 EL3 的常驻代码,任何一次 PSCI CPU_ON 都要回到这里执行。若把 Guest 内核加载到与 BL31 重叠的地址,典型现象是启动到某个 Guest 时系统直接挂死或复位,而不是给出明确报错。
三、多核启动:从 BootROM 到 PSCI
S32G 有多个 Cortex-A53 核。上电时并非所有核都从 BootROM 开始执行,通常只有一个核被 BootROM 选为引导核,其余核处于等待状态。引导核依次完成 HSE、BL2、BL31、U-Boot 和 Hypervisor 的加载,最后由 Hypervisor 通过 PSCI 的 CPU_ON 调用唤醒从核。BL31 收到 SMC 后,负责给目标核设置入口地址、异常等级和栈,再释放该核。
在虚拟化场景下,从核的入口地址通常指向 Hypervisor 的次级核启动代码,而不是 Guest 内核。Hypervisor 在次级核上完成每核的虚拟化初始化(如设置 HCR_EL2、VTCR_EL2、每核的 vCPU 上下文),然后才把该核交给某个 vCPU 调度。因此,多核启动失败最常见的原因有三类:一是设备树中 CPU 节点与 PSCI 使能属性不匹配,导致 Hypervisor 找不到可唤醒的核;二是 BL31 的 PSCI 版本或 CPU 数量配置与实际芯片不符;三是从核入口地址被 Guest 镜像覆盖。
四、搭建虚拟化环境的实操要点
搭建时建议按“先裸机、再 ATF、后 Hypervisor”的顺序逐级验证,每一级都保留可观察的输出。第一步,确认 HSE 固件版本与安全启动策略:如果启用了安全启动,所有后续镜像都必须签名,否则 BootROM 会在校验阶段停止。第二步,编译 ATF 时确认 BL31 的 PSCI 实现和平台端口,S32G 的电源域、复位控制器与通用平台不同,需要对应的平台代码。第三步,U-Boot 中通过 bootargs 和 bootcmd 指定 Hypervisor 镜像与 Guest 配置,并确保 cpu-release-addr 指向 BL31 的 PSCI 入口。
md 查看 BL31 所在内存是否被改写,用 cpu detail 或平台命令确认各核状态;进入 Hypervisor 后,通过串口日志确认每个 vCPU 是否成功上线,再检查 Guest 是否在 EL1 正常启动。五、启动顺序检查表
| 检查项 | 期望结果 | 异常表现 |
|---|---|---|
| BootROM 启动模式 | 从目标介质读取并验签通过 | 无串口输出或停在 ROM 代码 |
| HSE 固件 | 安全核就绪,可提供验签 | 后续镜像校验失败 |
| BL2 → BL31 | BL31 常驻 EL3,PSCI 可用 | 从核无法唤醒 |
| U-Boot | 加载 HV 与 Guest 镜像 | 镜像地址重叠、加载失败 |
| Hypervisor | EL2 接管,创建 VM | Guest 无法启动或反复复位 |
| Guest OS | EL1 运行,串口登录正常 | 内核 panic 或卡在 earlycon |