陈豪毅
← 全部项目

嵌入式软件

Rust Hypervisor(与 Dumarey 合⁠作)

为车规级功能安全场景开发基于 Rust 的 Type-1 虚拟化管理程序。

由都灵理工大学的教授与 Dumarey 的前技术官共同指导。

主要工作

  • 基于 Rust 为 Arm Cortex-R52 多核 MCU 开发 EL2 层 Type-1 虚拟化管理程序,为车规功能安全场景提供分区隔离
  • 实现静态分区架构:VM 原生运行于 EL1,经 HVC 请求 EL2 服务,由 stage-2 MPU 隔离内存;内存隔离与故障隔离已通过板上验证
  • 完成从 ROM 进入 EL2、RAM ECC、时钟与缓存初始化、VM 启动、HVC 和中断注入的板上验证,并实现跨集群多核启动
  • 使用英飞凌 svd2pac 从 SVD 描述生成 Rust 外设访问层,并构建片上外设与 eDMA 引擎的类型化模型
  • 搭建按 EL1、EL2 与宿主部署工具划分的 Rust SDK,将硬件相关代码隔离在板级层,支持逻辑部分在宿主机上测试
  • 利用 Claude Code 开发开源 Rust 命令行工具 tracebridge,基于 TRACE32 Remote API 实现 PowerView 启动、烧录、符号加载与 RTT 通信的自动化,作为上板回归工具的后端,并与 Lauterbach 官方的 t32mcp 配合,支持 AI agent 完成烧录与调试

背景与目标

Dumarey 正在研究把原本分散在多个 ECU 上的功能整合到一个 ECU 上的可行性。一旦整合,多个 RTOS、AUTOSAR 或裸机系统就要共用一颗多核车规 MCU,并且不能让一个系统悄悄破坏另一个系统。只靠多核各跑各的,资源归属只是软件约定:出错的系统可以改写自己的保护配置,也可以访问别的系统的外设。

本项目把最终的资源边界放在 VM 无法修改的 EL2。每个 VM 的核、内存、外设和中断在构建前静态确定,运行时由硬件机制强制执行:VM 可以收紧自己的权限,但不能扩大。

架构

Rust Hypervisor 的目标架构图:EL1 的 api、ipc、services、capi,经 abi 连接 EL2 的 policy、runtime、hal 和 platform,右侧是宿主工具链 config、deployment、codegen 和 CLI/GUI。

目标架构,点击查看大图。其中 EL1 的 ipc、services,以及宿主工具里的 deployment、codegen 和 CLI/GUI 尚未实现,当前进度见下表。

  • CPU:VM 直接运行在 EL1,没有二进制翻译;敏感操作、HVC 和中断进入 EL2。一个核最多运行一个 VM,不做分时调度。
  • 内存:Cortex-R52 用 MPU,没有 MMU。Stage-2 MPU 只检查权限,不做地址转换,所以每个 VM 按分配给它的物理地址链接,能隔离,但不能透明重定位。
  • 外设:每个外设只有一个所有者,其他 VM 向所有者请求服务,不直接访问。这部分还在设计中。
  • EL2 保持精简:驱动、协议栈和业务逻辑留在 VM 里,EL2 只做资源隔离和有界的服务。

当前进度

截至 2026 年 10 月底。“板上已验证”指在目标板上运行过,并由自动检查观察到相应行为。

能力 状态
启动:从 ROM 进入 EL2,先初始化 RAM ECC 再建栈,配置时钟、缓存和看门狗 板上已验证
进入 VM:校验镜像头,清理 VM 内存,进入 EL1 板上已验证
内存隔离(CPU 侧):VM 读、写、执行 EL2 内存都被挡住,VM 之间互读也被挡住,包括跨集群 板上已验证
HVC:调用往返,寄存器保持不变,未知功能返回错误 板上已验证
故障隔离:VM 出错只停下所在的核,其他核继续运行 板上已验证
中断:定时器中断注入 VM,电平触发的 SPI 路由 板上已验证
多核:主核拉起其他核,跨集群启动,所有核通过启动屏障对齐后才进入 VM 板上已验证
部署工具:配置解析已实现;资源分配、校验和代码生成未实现,部署数据目前手写 部分实现
总线侧隔离:DMA 和片上防火墙,CPU 侧的 MPU 管不到它们 未实现
VM 间通信:已写出规则提案,代码未开始 设计中
一个 VM 跨多个核 计划中
故障注入与恢复 计划中

最近一次全量上板回归在 2026 年 10 月 28 日:33 次镜像运行和 32 次复位检查全部通过。另有 103 个不需要板子的宿主测试。

工程难点

怎样证明隔离真的生效

调试器的访问绕过 MPU,读回寄存器只能证明配置写进去了,不能证明它在过滤访问。所以每条隔离性质都配了一个专门的故障镜像:让 VM 真的去读、写、执行不属于它的内存,再检查 EL2 记录的故障类型和地址,并确认其他核没有受影响。由被挡住的访问本身作证。

延迟测量查出缓存没有生效

测量经 EL2 注入和直通的中断延迟时,清空缓存前后的结果几乎没有差别,这不合理。用片上 trace 拆解路径后发现,不是某段代码慢,而是每次取新指令块都慢。根因是 IMP_CSCTLR 一直保持复位值:L1 缓存没有任何一路分给 Flash 接口,Flash 上的代码和常量完全不进缓存。这个寄存器只能在缓存打开之前写,于是改到每个核的启动路径里配置,并加入回归检查。修复后 EL2 的中断和 HVC 路径都明显变快,冷热缓存的差别也出现了。

多核启动时不留下半启动的系统

设计要求所有 VM 要么都进入,要么都不进入。从核完成准备后各报告一次,主核收齐后发布一次裁决。每个屏障字独占一个缓存行,并且只有一个写者:写方 clean 后 sev,读方 invalidate 后 wfe,等待有上限。GIC 的 distributor 每个集群一个,只有本集群的核访问得到,所以由各集群内序号最小的核负责配置。

下一步

  • 补上总线侧隔离:片上防火墙和 DMA,这是 CPU 侧论证覆盖不到的部分
  • 实现 VM 间通信:单向共享内存加事件通知,EL2 不搬运消息内容
  • 研究面向车规 MCU 可靠性的容错机制,单粒子翻转(SEU)是所考察的故障类型之一。计划用芯片的一个核配合 TRACE32 向运行中的分区注入故障,记录 Hypervisor 的检测、隔离与恢复表现