第二十七周工作总结
概述
rt-async-amp 在 QEMU virt 双核 AMP 方案验证可行后,下一步是移植到真实硬件——进迭时空 K3 SoC 的 RT24 实时小核。本周完成了 K3 RT24 启动机制的全链路调研:从 BootROM 到 RT24 执行第一条指令,每个环节都定位到确切的源码/寄存器。
核心结论:rt-async 可在 RT24 上运行,且无需自实现唤醒逻辑——复用官方 esos.itb 打包链即可。
1. 目标平台
K3(进迭时空 2026 年 1 月量产的 RISC-V AI SoC)采用大小核 + 实时核的异构设计:
| 核 | 类型 | 数量 | 职责 |
|---|---|---|---|
| X100 | 通用大核 (RV64GV) | 8 | 跑 Linux |
| A100 | AI 核 | 8 | GPU/AI 计算 |
| RT24 | 实时小核 (CVA6, RV64GC) | 2 | 能效管理、实时任务 |
两个 RT24 核(os0_rcpu / os1_rcpu)各自跑独立 RTOS 实例,正是 rt-async 的目标落点。RT24 关键参数:主频 614.4 MHz、os0 链接地址 0x100200000(os1 0x100800000,DDR >4GB)、每核独立 3 MB RAM、官方固件 ESOS(RT-Thread 4.0.4)。
2. 启动链全链路(核心成果)
之前调研卡在"ELF 加载到 DDR 后,靠什么让 RT24 开始执行"。最终通过 Yocto BSP 仓库定位到真正的 K3 U-Boot(spacemit-com/uboot-2022.10,tag k3-br-v1.0.0),把整条链补全:
① BootROM
└─ 读 STRAP 引脚确定启动介质,加载 U-Boot SPL 到 SRAM 并跳转
② U-Boot SPL (board/spacemit/k3/)
├─ DDR/PMIC/pinctrl 初始化,注册 k3-rproc 驱动
├─ 从存储读取 esos.itb + u-boot.itb
└─ 解析 FIT 时逐节点回调 board_fit_image_post_process()
├─ "rcpu0-fw" → rproc_load(0) + rproc_start(0) ← 唤醒 RT24 核 0
├─ "rcpu1-fw" → rproc_load(1) + rproc_start(1) ← 唤醒 RT24 核 1
└─ u-boot/dtb → 正常加载到 DDR
③ RT24 被唤醒 (drivers/remoteproc/k3-rproc.c)
└─ 从 0x100200000 取指,执行 startup_gcc.S: _start
④ OpenSBI fw_dynamic → U-Boot proper → Linux
(此时 RT24 早就在跑了)三个关键证据:
- FIT 镜像结构(
esos_rt24.its):rcpu0-fw节点的load/entry均为<0x1 0x200000>(#address-cells=<2>的 64 位写法,即0x100200000),data指向rt24_os0_rcpu.elf.lzo。 - SPL 触发 rproc(
board/spacemit/k3/spl.c):board_fit_image_post_process()识别rcpu*-fw节点名,LZO 解压 ELF 后调用rproc_load+rproc_start。唤醒发生在 SPL 阶段,早于 OpenSBI 和 Linux——主核内核里完全没有 RT24 管理代码(已全树搜索确认)。 - 唤醒的确切寄存器(
drivers/remoteproc/k3-rproc.c):k3_rproc_load()解除音频域复位、开时钟、允许 RT24 执行、保持复位睡眠、解析 ELF 段拷到 DDR;k3_rproc_start()设启动入口 PC、设 mhartid、解除软件复位、写唤醒寄存器、轮询同步标志确认 RT24 起来。整个唤醒不依赖 mailbox、不依赖 SBI ecall,是纯寄存器操作。
3. RT24 视角的硬件
ESOS 设备树给出 RT24 自己看到的地址空间,与主核视角不同:
| 外设 | RT24 视角 | QEMU virt 现状 | 差异 |
|---|---|---|---|
| 中断控制器 | PLIC 0xe0000000 | PLIC 0x0c000000 | 仅地址不同,模型一致 ✓ |
| 定时器 | rtimer0 0xc0889000 | CLINT mtime | 寄存器模型不同,需重写 |
| UART | R_UART0 0xc0881000 (PXA-uart) | NS16550A | 寄存器布局不同,需重写 |
| UART 时钟 | 需先经 CCU 0xc0881f00 使能 | 默认开启 | 加 clk_init() |
| IPI / 通信 | mailbox3~7 | CLINT MSIP | 机制不同,需适配 |
| 关机 | 无 SiFive Test 设备 | 写 0x5555 | 改为 wfi 循环 |
中断控制器是 PLIC(不是 APLIC)——最大的好消息,rt-async 现有 PLIC 驱动逻辑可基本复用,只需改地址。
4. 移植可行性评估
架构层完全兼容:ESOS 启动汇编 startup_gcc.S 与 rt-async 的 __start(riscv64-rt/src/start.rs)结构高度一致——清 mie/mip、设 mtvec/gp/sp、清 bss 各步骤都对应得上,trap 入口同样是标准 M-mode 上下文保存/恢复,可直接复用。唯一需处理的是启动禁 FPU(ESOS 设 MSTATUS_FS,当前 rv64imac 无 FPU)。
加载层零额外工作:把 rt-async 编译出的 ELF 放进 esos.itb 的 rcpu0-fw 节点,SPL 会自动 rproc_load + rproc_start。复制 esos_rt24.its 把 data 换成自己的 ELF,mkimage 重打包即可。
待解决的移植点:
| 工作项 | 难度 | 说明 |
|---|---|---|
memory.x 改址 0x100200000 | 低 | 改 ORIGIN/LENGTH |
ISA target 切 riscv64gc | 中 | 验证 bare-metal target;启动禁 FPU |
重写 Chip::put_str (PXA-UART) | 中 | 参考 ESOS ruart 驱动 |
UART 时钟使能 (clk_init) | 低 | 写 CCU 0xc0881f00 |
重写 TimerChip (rtimer0) | 中 | 32-bit 计数器 + match 寄存器 |
PLIC 改址 0xe0000000 | 低 | 改 base + context 号 |
删除 shutdown (SiFive Test) | 低 | 改为 wfi 循环 |
| IPC:CLINT MSIP → mailbox | 中 | AMP 通信机制需重新设计 |
5. 踩坑教训
调研耗时较长,主因几次走错方向:
- 找错 U-Boot 仓库:
spacemit-com/u-boot只有 K1 代码,正确的 K3 U-Boot 是spacemit-com/uboot-2022.10(tagk3-br-v1.0.0),由 Yocto BSP 帖子才定位到。 - 误判加载阶段:一度以为是 U-Boot proper 用
bootm standalone加载,实际是 SPL 阶段的rproc_load/rproc_start。 - 误判触发机制:猜测过 mailbox/SBI ecall,最终确认是纯 PMU + 复位寄存器写入。
根本教训:调研技术机制时,定位到源码行号之前不要下结论。 "某仓库只有 K1"和"某仓库存在 K3"是两个不同的事实,不能因前者推断后者不存在;查不到就直接说查不到,不要用"某种机制""可能"等含糊措辞。
6. 下周计划
启动 rt-async 移植第一阶段——先在 RT24 上点亮 UART:
- 新建
modules/chip-k3-rt24/(参考现有chip-qemu-virt-rt) - 实现 PXA-UART 的
Chip::put_str+ CCU 时钟使能 - memory.x 改为
0x100200000,验证链接 - 用
esos_rt24_sign.its(无压缩)打包 rt-async ELF - 目标:在 K3 板子 R_UART0 上看到 rt-async 的启动日志
定时器和 PLIC 留到第二阶段,UART 通路先打通。
参考资料
源码仓库(本周实际查阅)
- esos(官方 RT24 固件,RT-Thread 4.0.4):https://github.com/spacemit-com/esos
- 启动汇编
libcpu/risc-v/spacemit/rt24/startup_gcc.S、链接脚本bsp/spacemit/platform/rt24/os0_rcpu/gcc.ld - FIT 模板
esos_rt24.its/esos_rt24_sign.its、ENTRY_POINTbuild.sh:110(0x100200000) - 设备树
bsp/spacemit/platform/rt24/k3.dtsi
- 启动汇编
- uboot-2022.10(K3 U-Boot,tag
k3-br-v1.0.0):https://github.com/spacemit-com/uboot-2022.10- SPL 主流程
board/spacemit/k3/spl.c、额外 FIT 加载board/spacemit/k3/spl_extra_fit.c - RT24 唤醒驱动
drivers/remoteproc/k3-rproc.c(k3_rproc_load/k3_rproc_start,含全部寄存器定义)
- SPL 主流程
- linux-k3(分支
k3/integration):https://github.com/spacemit-com/linux-k3 — 内核中无 RT24/remoteproc 管理代码 - spacemit-yocto(K3 Yocto BSP,分支
k3):https://github.com/yingjie-liu-spacemit/spacemit-yocto — 指向上述源码仓库的 recipe
官方文档
- K3 用户手册(地址映射/中断/外设寄存器):https://cdn-resource.spacemit.com/file/chip/K3/k3_um_en.pdf
- K3 Yocto BSP 上线公告:https://forum.spacemit.com/t/topic/1239
- 官方文档中心:https://www.spacemit.com/community/document