24
社区成员
发帖
与我相关
我的任务
分享原文标题: Jailhouse hypervisor on MediaTek Genio: bare-metal isolation on Linux
来源: ProventusNova 技术博客
原文链接: https://proventusnova.com/blog/jailhouse-hypervisor-mediatek-genio/
文本状态: 原文技术状态标注为 2026 年 7 月,本解读整理于 2026 年 10 月
Jailhouse 上游对 ARM64 的支持是"架构通用"的。文档会说明 cell 配置包含哪些字段、hypervisor 如何接管 EL2,但不会说明某颗具体 SoC 上这些字段应当填什么值。MediaTek Genio 平台恰好属于文档缺失最严重的一类:SoC 技术参考手册不公开发布,平台特有的中断路由与引脚复用机制在上游代码中也没有对应实现。
这篇文章的价值在于,把移植过程中"靠调试反推"得到的知识以可复现的形式写了下来,并给出了 Genio 720 上的真实取值。
| 组件 | 异常级 | 职责 |
|---|---|---|
| Jailhouse hypervisor | EL2 | 维持分区边界,不参与调度 |
| Linux 根单元 | EL1 | 应用栈、网络、OTA,占用绝大部分核与内存 |
| Zephyr 非根单元 | EL1 | 硬实时任务,独占所分配到的核、内存与外设 |
Genio 720 为 8 核配置(2×Cortex-A78 + 6×Cortex-A55)。参考配置中 Linux 保留 6 至 7 核,Zephyr 非根单元独占 1 个 A55 核。
选择 A55 而非 A78 作为实时核的考虑是:实时任务对单核峰值性能要求不高,对确定性要求很高;A78 留给 AI 推理的收益更大。
关键性质:非根单元中的代码不受 Linux 调度器行为、中断风暴或缓存污染影响。这是分区方案相对 RT 补丁的本质区别——后者仍然是同一个内核调度同一批核。
三者缺一不可,缺少任何一个 Jailhouse 都无法完成初始化。值得注意的一点是:上游 Jailhouse 文档不会提及这些补丁,因为它们不属于 Jailhouse 项目维护的内容,而属于平台适配层。
文件:arch/arm64/kernel/hyp-stub.S
ENTRY(finalise_el2)
ret /* 提前返回,不启用 VHE */
...
EXPORT_SYMBOL_GPL(__hyp_stub_vectors)
原理:ARMv8.1 引入的 VHE(Virtualization Host Extensions)允许 Linux 内核直接以 EL2 运行,从而占用该异常级。而 Jailhouse 需要占据 EL2,因此必须阻止 Linux 在启动阶段接管它。finalise_el2 是内核决定是否启用 VHE 的位置,在此提前返回即可将 EL2 保留给 hypervisor。同时需要导出 EL2 stub 向量表供 jailhouse.ko 使用。
文件:mm/vmalloc.c
EXPORT_SYMBOL_GPL(ioremap_page_range)
EXPORT_SYMBOL_GPL(__get_vm_area_caller)
这两个符号由 jailhouse.ko 在运行时调用,用于建立 hypervisor 自身的内存映射空间。上游内核未导出它们,需要显式导出。
reserved-memory {
jailhouse@44000000 {
reg = <0x0 0x44000000 0x0 0x1000000>; /* 16 MB */
no-map;
};
};
no-map 属性确保 Linux 既不建立该区域的地址映射,也不将其纳入内核的物理内存管理范围。这是保证 hypervisor 内存不被 Linux 触碰的可靠手段。
原文提到一个容易被忽略但很关键的点:hypervisor 预留区不得与 Linux 内核镜像重叠。Genio 700/720 平台上从 Linux 5.x 升级到 6.6 时,内核镜像体积增大,预留基址因此需要下移约 48 MB。
这引出分区架构的一项固有约束:内存布局是静态的,内核镜像尺寸一变,整个布局就需要重新计算。这与动态方案(由 hypervisor 在运行时仲裁内存)形成对比——静态分区换来了确定性,代价是布局调整需要人工介入。
cell 配置本质上是一段 C 结构体,由 Jailhouse 工具链编译为二进制 .cell 文件。
.platform_info = {
.gic_version = 3,
.gicd_base = 0x0c000000,
.gicr_base = 0x0c040000, /* 2MB,覆盖 8 个 CPU 重分发器 */
.maintenance_irq = 25,
},
对这四个取值的核对:
gic_version = 3 与 GIC-600/700 系列对应。Genio 720 属新一代 SoC,在该层级采用 GICv3 属预期结果。0x0C040000 − 0x0C000000 = 0x40000,即 256 KB,恰为 GICD 区域的典型尺寸。两个基址按 256 KB 边界对齐排布。0x40000。相较 GICv3 规范的最小帧 128 KB(RD_base + SGI_base),256 KB 步进说明采用了含额外帧的布局。这同时反推出该 SoC 的 GICR 帧步进参数——移植到同系列其他型号时可直接沿用。maintenance_irq = 25 属体系结构规定值:GICv3 中 PPI 的 INTID 范围为 16 至 31,PPI 9 对应 INTID 25,即非安全态 EL2 的维护中断。该值不随平台变化,若在其他 GICv3 平台上看到同样的 25,属正常现象。这一节是全文对社区最有价值的部分,也是上游文档完全没有覆盖的内容。
在标准 ARM 平台上,外设直通只需两步:
disabled,避免 Linux 抢先接管在 Genio 平台上仅做这两步并不够。 MediaTek 的引脚复用(pin mux)与中断路由由专用控制器管理,不经过标准 GIC 通路。因此 cell 配置中需要额外的 .vendors 数组:
.vendors = {
JAILHOUSE_VENDOR_MTK_GPIO,
JAILHOUSE_VENDOR_MTK_EINT,
},
其作用是让 hypervisor 在建立分区时一并配置引脚复用寄存器与外部中断(EINT)路由,使非根单元在拿到外设后能够真正收到中断。
这一设计的意义超出 Genio 平台本身:它表明 Jailhouse 的 cell 配置具备厂商扩展机制。对于需要在其他厂商 SoC 上处理非标准中断控制器的移植工作,.vendors 数组提供了一条既有的扩展路径,无需改动 hypervisor 主体。这是移植方法论层面的参考价值。
Genio 720 参考配置:
| 项目 | 分配情况 |
|---|---|
| Linux 根单元 | 6 至 7 个核、绝大部分内存、完整外设访问 |
| Zephyr 非根单元 | 1 至 2 个独占核、48 MB 隔离内存、UART + GPIO + EINT 直通 |
| Jailhouse 自身 | 16 MB @ 0x44000000 |
| IVC 通信区 | 4 KB @ 物理地址 0x80000000 |
内存规划遵循的原则与 Jailhouse 官方建议一致:非根单元的内存与外设数量尽可能小。理由有两层——其一,中断源越少,最坏情况时延分析越容易收敛;其二,非根单元侧没有 Linux 那样的驱动生态,每多一个外设就多一份需自行维护的裸机或 RTOS 驱动。
Linux 与 Zephyr 之间通过 IVSHMEM 通信。IVSHMEM 在两个单元中都呈现为一个虚拟 PCI 设备,Jailhouse 在其上提供 IVC(Inter-VM Communication)通信 API。
Genio 720 上 IVC 区域为物理地址 0x80000000 处的 4 KB 共享内存。
这一设计对熟悉 Jailhouse 多单元通信的开发者而言并不陌生:共享内存加中断通知,是静态分区架构下最直接的数据通路方案。
这是原文后半段的重要更新内容:
meta-mediatek-experimental Yocto 层中发布 Jailhouse 配方genio-510-evk.cell、genio-720-evk.cell,以及对应的 -zephyr 非根单元配置,另有 UART 演示与中断时延测试配置JH_CONFIG_INMATE_BASE 控制,内存布局不同时可调整Zephyr 侧的初始化与构建:
west init -m https://github.com/ffreimann-mtk/zephyr --mr MTK-Genio_4.3.0 ~/zephyrproject
cd ~/zephyrproject && west update
west build -b genio_700_evk samples/
板端生命周期与标准流程一致:
modprobe jailhouse
jailhouse enable /lib/firmware/jailhouse/genio720-evk.cell
jailhouse cell create /lib/firmware/jailhouse/genio720-evk-zephyr.cell
jailhouse cell load <cell> zephyr.bin
jailhouse cell start <cell>
jailhouse cell list
变化的是起点,不是概念。配置结构、厂商特有处理、内存容量规则这三者在已发布代码中依然需要逐一理解和调整,这也正是这篇文章仍具参考价值的原因。
原文明确给出了判断标准。这一点值得肯定——很多厂商材料只讲优势不讲边界。
适用场景:
不适用场景:
CONFIG_PREEMPT_RT 或处理器亲和性绑定时延量级对照(引自其关联文章):
| 方案 | 最坏情况时延 | 隔离程度 |
|---|---|---|
| 通用 Linux | 毫秒级 | 无 |
| PREEMPT_RT | 50–150 μs | 软隔离 |
| Jailhouse 非根单元 | < 10 μs | 硬件隔离 |
| M 核独立 RTOS | 1–10 μs | 完全独立硬件 |
ProventusNova 是一家嵌入式软件咨询公司,业务范围收得很窄:只做 NVIDIA Jetson 与 MediaTek Genio 两个平台。其自我定位为"在文档终结之处工作"——专攻硬件到货之后、软件可用之前的那段调试期。
| 项目 | 内容 |
|---|---|
| 注册主体 | PROVENTUS NOVA LTD(英国,公司编号 15678169) |
| 成立时间 | 2024 年 4 月 |
| 技术负责人 | Andrés Campos(CTO 兼联合创始人) |
| 官方资质 | MediaTek IoT 合作伙伴目录中的"系统集成技术合作伙伴" |
服务内容(均为固定报价,不按小时计费):
| 服务 | 交付周期 | 技术内容 |
|---|---|---|
| 定制载板 Bring-up | 7 天 | 电源时序、bootloader、内核、高速接口 |
| CSI 摄像头驱动 | 14 天 | MIPI CSI-2、V4L2、ISP 调优、GStreamer |
| GMSL 摄像头驱动 | 1 个月 | SerDes 驱动栈、虚拟通道映射、多路同步 |
| GStreamer 流水线 | 14 天 | 硬编解加速、零拷贝、RTSP |
| EdgeAI 部署 | 14 天 | TensorRT 优化、量化、DLA 映射 |
| ODM 对接与硬件选型 | — | BSP 级原理图评审 |
公开技术资产方面,该公司维护一个公开的开发者 Wiki(developerwiki.proventusnova.com),内容涵盖 Jetson Linux BSP 与内核源码搭建、DTB 构建、摄像头绑定验证等实操流程,含具体命令与预期输出。这批材料的详细程度高于其官网的服务介绍页面。
客观评估这篇文章的贡献:
.vendors 数组这一设计为其他平台的移植工作提供了可借鉴的扩展路径。需要留意的地方:
meta-mediatek-experimental 层名称中的"experimental"已表明其成熟度定位,用于产品设计时需评估其稳定性承诺。对 Jailhouse 中文社区的开发者而言,这篇文章的价值主要在两处。
其一是 Genio 平台移植的具体路径:三个内核补丁、vendor 扩展字段、可核对的内存与中断分配参数,都是可直接复用的信息。
其二是方法论层面的示范:当平台文档缺失时,如何通过内核补丁与配置扩展把 Jailhouse 跑起来。这一思路的适用面比前者更广——任何面对非公开技术参考手册的 SoC 移植工作,都可以参照同样的入手顺序:先从 EL2 接管、符号导出、内存预留三处入手,再针对厂商特有的中断与引脚控制机制做配置扩展。