setenv ipaddr 10.12.1.205;setenv serverip 10.12.1.200;tftp 0x800000 bsprk3588_owl_ai_box_plus_v10_x64.bin;go 0x800000
rk3588 启动 4 核无问题,启动 8 核出现乱码以及死机问题。
分析代码,对 psci 接口进行更新,启动 4 核,系统成功启动
修改设备树文件,启动 5 核,第 5 核输出回应,但随后出现死机现象
修改汇编启动代码和多核启动入口代码,添加打印,测试结果如下:
理论上,5 核应跳转至 reset 处开始执行,打印 “cpu++” 以及二级入口等字符串。但是,实际结果并未有输出。猜测 5 核接收 SMC 指令后,固件进行了响应,但是 5 核出现问题,无法启动,导致主核出现死循环现象,现象由 bsp 代码结构造成。
主核与从核配置均由内核代码提供,从其他角度考虑。5 核启动后没有任何输出,怀疑 5 核启动时,供电是否正常,打印电压状态寄存器排查。结果如下:
结果表明,多核启动时供电正常,故排除因供电问题导致的多核启动失败。
修改汇编启动代码,进行测试,发现 5 核发生执行动作,并进入二级启动入口,结果如下:
测试 6 核:
测试 7 核:
测试 8 核:
多核启动方式
ARM 目前提供的多核启动有两种,分别为 spin-table 和 psci。rk3588 采用 psci 模式启动多核,该模式涉及 ARM-V8 异常等级,SMC 指令以及 ATF 固件等内容。执行过程如下:
- 上电后,ATF 固件会将从核在 bootloader 阶段陷入挂起的状态;
- 操作系统启动后,通过 SMC 指令陷入 EL3 异常并产生 EL3 中断;
- ATF 固件配置了 EL3 异常处理,因此,对 EL3 中断进行响应并处理,从而启动从核。
(注:关于 ATF 的具体执行, 不做分析)
(注:spin_table 在 u-boot 中可进行操作, 因此不需要 ATF 固件)
psci 实现 (参考 Linux)
Linux 通过设备树获取 psic 信息,并以驱动形式注册 psci 操作接口。随后,psci 接口将被全局变量 cpu_ops 关联。多核启动则是 Linux 通过 cpu_ops 简介调用 psci 的操作接口,从而执行从核的启动与关闭等操作,这些操作均和 SMC 指令有所关联。
ARM-V8 架构的启动
上电后,硬件复位,开始启动内置 boot rom 中的 1级 bootloadr;
1级 bootloader 加载 2级可信固件并启动;
2级加载并启动 3级可信固件并为操作系统的启动提供接口.
启动流程图
(注: BL – bootloader)
BL1 位于 ROM 中,在 EL3 等级下从 1 级引导的 reset 位置开始运行,并将 2 级引导镜像加载到 SRAM 中。
BL2 位于 SRAM 中,在 secure EL1 等级下运行,依次加载 BL31、BL32、BL33 镜像。
BL2 将控制权交给 BL1,BL1 关闭 MMU 和 CACHE,随后,BL1 将控制权交给 BL31;BL31 交给 BL32;BL32 交给给 BL33。
上述过程所说的异常等级为:
EL0:普通用户应用程序;
EL1:操作系统;
EL2:虚拟化管理程序;
EL3:低级别的固件。
上述 BL31 和 BL32 实际为 ATF 固件。ATF 中包含了不同的组件,查阅资料,目前可确定多核启动相关的组件有 TF-A 和 OP-TEE。
TF-A 和 OP-TEE 将中断划分为本地中断和是外部中断,将 SMC 指令产生的中断默认为本地中断。整体的执行书讯如下图所示:
(注:这里可将 TF-A 默认为 secure monitor,ATF 固件包含的东西较多)
附件:arm-v8 64 位寄存器
通用寄存器
特殊寄存器
系统寄存器
系统控制寄存器