1. 课程导入
Xen 是 Type-1 裸机型 Hypervisor 的代表实现,它在硬件与操作系统之间插入一层极薄的虚拟化抽象,使多个 Guest OS 能够以接近原生的性能共享同一颗 SoC。在 x86 服务器领域,Xen 的移植与启动路径已经相当成熟;而到了 ARM 平台,由于缺少统一的固件接口、设备树描述方式各异、启动异常向量与特权级模型完全不同,移植工作呈现出鲜明的“平台工程”特征。本课程的目标,就是把这套从源码到板级点亮、从 Hypervisor 启动到 Domain 0 引导的完整链路拆解清楚。
一、学习目标:从“能编译”到“能启动、能调试”
本课程不满足于让学员跑通一次编译,而是希望建立三层能力。第一层是结构认知:理解 Xen on ARM 的镜像组成、启动阶段划分、特权级切换与内存布局。第二层是工程能力:能够为一块具体开发板配置设备树、裁剪配置项、交叉编译并生成可引导镜像。第三层是排障能力:当串口只输出半行日志、当 Domain 0 卡在 earlycon、当 SMMU 报出 fault 时,能够依据启动时序定位问题环节。
二、核心概念:理解 Xen ARM 的四个关键词
- EL2 与 HYP 模式:ARMv8 中 Xen 运行在 EL2,Guest OS 运行在 EL1,用户态在 EL0。EL2 是虚拟化的“控制层”,负责陷入捕获、阶段 2 地址翻译和中断路由。
- Domain 0(Dom0):Xen 启动后创建的第一个特权虚拟机,承担驱动、工具栈与后续 Guest 的管理职责。没有 Dom0,Xen 只是一个空壳。
- 设备树(Device Tree):ARM 平台没有 ACPI 那样的统一枚举机制,硬件拓扑、中断控制器、串口、内存区域都通过 DTB 描述。Xen 自身需要一份 DTB,Dom0 也需要一份(通常由 Xen 加工后传递)。
- 启动链(Boot Chain):典型路径为 BootROM → BL1/BL2 → BL31(ATF)→ U-Boot → Xen → Dom0 Kernel → RootFS。每一级都可能成为移植的“卡点”。
三、整体框架:一张图看清启动信号链
下图给出 Xen ARM 平台从固件到 Dom0 的关键阶段与特权级迁移关系。它既是本课程的知识地图,也是后续排障时的对照基准:任何一次启动失败,都可以先判断“停在哪一级、当前处于哪个 EL、串口是否已经由 Xen 接管”。
四、方法流程:一条可复用的移植主线
面对一块新板子,建议按下面的顺序推进,而不是一上来就改代码。顺序本身就是一种排障策略:每一步都留下可验证的输出。
- 确认硬件与固件基线:确认 SoC 型号、ATF 版本、U-Boot 是否支持 EL2 启动、串口基地址与波特率。
- 准备设备树:从内核或厂商 BSP 中取板级 DTS,确认
hypervisor节点、psci节点、interrupt-controller与memory描述完整。 - 配置与编译 Xen:选择
xen_defconfig或板级 defconfig,设置交叉编译器与目标架构。 - 打包引导镜像:将 Xen、Dom0 内核、DTB、initrd 按 U-Boot 可识别的格式组织。
- 串口验证与逐级排障:先看 ATF/U-Boot 是否正常,再看 Xen 是否打印版本号,最后看 Dom0 是否进入用户态。
# 典型交叉编译与镜像准备(示意)
export CROSS_COMPILE=aarch64-linux-gnu-
make xen_defconfig
make -j$(nproc) xen
ls -lh xen/xen
# 生成镜像后,与 dom0 Image、xen.dtb 一起放入 boot 分区
五、案例场景:一块新开发板的首次点亮
假设你拿到一块基于 ARMv8 的开发板,厂商只提供了 U-Boot 和 Linux 内核,没有 Xen 支持。第一次启动时,串口可能只输出到 U-Boot 就停止,或者 Xen 打印了版本号却在 create_dom0 处挂起。此时不要盲目改代码,而应回到启动链:先确认 U-Boot 是否以 EL2 进入 Xen,再确认 Xen 是否成功解析 DTB 中的内存节点,最后确认 Dom0 的 bootargs 中 console= 与 earlycon 是否与真实串口一致。多数“首次点亮失败”都源于设备树与内存布局,而非 Xen 核心逻辑。
bootargs 日志。串口是 ARM 平台最可靠的“调试器”。
六、误区与复盘:新手最容易踩的四个坑
| 误区 | 表现 | 纠正思路 |
|---|---|---|
| 把 x86 经验直接套用 | 找不到 ACPI、试图用 GRUB 引导 | ARM 依赖 DTB 与 U-Boot,启动链完全不同 |
| 忽略 EL 级别 | Xen 无法获得 HYP 权限,陷入失败 | 确认 ATF/U-Boot 将 CPU 置于 EL2 |
| DTB 一份走天下 | Dom0 看不到串口或内存不足 | Xen 与 Dom0 的 DTB 需分别校验 |
| 只看内核日志 | 错过 Xen 早期输出,误判卡点 | 从 BootROM 开始逐级确认串口输出 |
七、学习路径:本课程如何展开
后续章节将沿着“环境与工具 → 启动原理 → 设备树与配置 → 编译与镜像 → Dom0 引导 → 调试与优化”的主线推进。每一章都会围绕一个可验证的工程目标展开,并配有对应的命令、配置或日志片段。你在本章建立的整体框架,会在后续每一次排障中被反复调用:先定位阶段,再定位特权级,最后定位具体模块。
现在,请先记住这条主线:固件把 CPU 交给 Xen,Xen 在 EL2 建立虚拟化环境,再把 EL1 交给 Domain 0。理解这条链,就理解了 Xen ARM 移植与启动工程的全部起点。