QEMU 常被介绍成一种虚拟机工具。这个说法足够开启教程,却不足以解释为什么它至今仍在开放基础设施里占据中心位置。更准确地说,QEMU 是一台边界机器:它决定哪些部分必须在用户态仿真,哪些部分可以交给宿主内核或平台 hypervisor 加速,哪些机器状态需要暴露为可管理接口,哪些存储与设备配置又必须保持明确。[1][2][3][4][5]
也正因这些边界,QEMU 才会出现在许多不同场景里。它可以为操作系统开发启动异构架构;可以借助 KVM 加速运行同架构 Linux 客户机;可以成为 libvirt 管理虚拟机背后的设备模型;还可以服务于测试农场、嵌入式固件、云镜像、CI runner、在线迁移路径和块设备实验。贯穿这些场景的共同主题,是一套有章可循的职责分割,而不止是“一个方便的虚拟机程序”。[1][6][7]
图片说明:题图是一张 2007 年 Fabrice Bellard 的真实照片,他是 QEMU 的原始作者。它适合这篇架构笔记,因为 QEMU 的长久重要性来自一种精确的设计直觉:让机器边界可以被编程,拒绝把客户机简化成一道进程,或简化成一只硬件盒子。[8]
TCG 是可移植性的底座
QEMU 的 Tiny Code Generator,简称 TCG,是它的可移植性底座。QEMU 仿真文档把 TCG 描述为这样一种机制:它让 QEMU 能在受支持的宿主平台上仿真多种客户机 CPU 架构,并视客户机架构支持 system emulation 或 user-mode emulation。[2] 这使 QEMU 不只是本地 CPU 功能的一层包装。
TCG 最重要的时刻,出现在宿主机无法直接执行客户机架构的时候。x86 工作站可以跑 Arm 固件,开发者可以在目标硬件不方便取得之前测试 RISC-V 软件镜像,构建系统也能在没有备齐所有实体板卡的条件下跨架构验证行为。TCG 不会是每个工作负载的性能答案,但它回答了一个更根本的架构问题:这台机器能不能在这里存在?
这个区别让 QEMU 在“虚拟化”一词并不合适的地方仍然有用。跨架构仿真、板级 bring-up、指令级调查、固件测试和客户机调试,都需要一条软件翻译路径。TCG 给了 QEMU 这条路径,所以即使宿主机没有匹配的虚拟化扩展,QEMU 仍能发挥作用。[2]
KVM 属于加速边界,仍要与 QEMU 分工
当宿主机与客户机架构相匹配时,QEMU 可以使用 accelerator。QEMU 的 system emulation introduction 把 KVM、Xen 这样的 accelerator 与 TCG 并列说明,并明确指出默认的 TCG 是纯仿真;要使用硬件虚拟化,就必须选择 accelerator。[1] Linux KVM API 文档展示了这条边界的另一面:用户态打开 /dev/kvm,创建 VM 与 vCPU 文件描述符,并通过 ioctl 控制虚拟机。[3]
日常说法很容易把这层关系抹平。人们会说“KVM VM”或“QEMU/KVM”,听起来像是在描述同一个组件。可是从运维角度看,区分很要紧。KVM 提供的是硬件辅助执行的内核接口。QEMU 仍要塑造这台机器:内存布局、设备模型、块后端、monitor 接口、迁移行为,以及大量客户机可见的硬件表面。
Ubuntu Server 的 QEMU 指南也从操作侧给出了同样的判断:QEMU 是机器仿真器,但它经常与 KVM 内核组件协同作为 virtualizer 使用,让客户机使用硬件虚拟化。[7] 这句话几乎就是整个架构的缩写。KVM 能让兼容的 CPU 执行变快,却不会让机器的其余部分消失。
机器不只是 CPU
QEMU 手册说,system emulation 提供的是一台机器的虚拟模型:CPU、内存和被仿真的设备。[1] 这个说法值得认真看待。客户机操作系统很少启动在“一个 CPU”里;它启动在某种板卡或平台契约里:总线、存储控制器、网卡、定时器、固件假设、中断控制器和启动顺序。
QEMU 的 device emulation 文档把这些细节摊开。设备有呈现给客户机的 front end,也有描述宿主资源如何被使用的 back end。设备总线取决于选择的 machine model。额外设备可以通过显式选项指定、查询与挂接。[6] 一条看似简单的 VM 启动命令,背后藏着一整套机器描述选择。
这也解释了 QEMU 作为测试工具的价值。你能够改变的是整台机器,范围超过单个程序文件本身。你可以比较不同设备选择,挂接另一种磁盘后端,测试启动路径,或复现一种客户机可见的硬件安排,减少对实体库存的等待。代价是 QEMU 命令行和管理层会变得很密。好处是这种密度对应真实边界,属于必要的工程表达。
QMP 把客户机变成可运维对象
如果操作人员不能检查和控制机器,机器边界就还不完整。QEMU Machine Protocol,简称 QMP,就是面向机器的控制表面。它的规范把 QMP 描述为一种 JSON 协议,应用程序可用它在机器层面操作 QEMU。[4] 这并不只是更漂亮的 monitor 语法。它决定了你是在启动一个客户机,还是把一个客户机纳入受管理系统。
QMP 让其他工具可以理解 QEMU。管理层可以协商能力、发出命令、接收异步事件,并把机器状态当成 API 表面,避免把控制过程留在一段封闭的终端会话里。[4] 因此,QEMU 能安放在更高层工具之下,操作员也可以少背一套专门命令行。
这里的设计教训不限于 QEMU。一个系统若要成为基础设施,其控制面就需要有类型、可自动化、可观察的边界。QMP 是 QEMU 能坐在 libvirt 式工作流、云编排、测试框架和专用 VM 工具下方的原因之一,同时它又不用放弃那些让自己最初有用的底层细节。[1][4]
存储必须保持明确
虚拟磁盘是另一个 QEMU 拒绝把现实压扁的地方。磁盘镜像文档列出多种受支持的镜像格式,包括 raw 与 qcow2,并说明 snapshot mode、VM snapshot、可增长镜像、压缩,以及 qcow2 的多快照支持等特性。[5] 这些细节属于正文。它们决定性能、可恢复性、可移植性和故障行为。
raw 镜像简单,也容易导出给其他仿真器。qcow2 则功能更丰富,支持更小的可增长镜像、压缩和多个 VM snapshot。snapshot mode 可以把写入转向临时存储,而 VM snapshot 会在特定约束下包含 CPU 状态、RAM、设备状态与可写磁盘内容。[5] 每个选择都会改变客户机的运维事实。
所以,严肃的 QEMU 部署不该把 -drive 或 -blockdev 配置看成偶然的管道细节。存储后端属于机器契约的一部分。cache mode、镜像格式、snapshot 语义、宿主文件系统行为和备份路径都应该进入设计评审,因为客户机会把它们的后果体验为延迟、耐久性或意外。
真正有用的采用问题
评估 QEMU,最好不要只问它是否“快”或“简单”。这些词会把太多不同情况揉在一起。更好的问题是:你究竟需要哪条边界?
- 你需要跨架构存在吗?那么 TCG 就是关键路径。[2]
- 你需要在 Linux 上获得同架构性能吗?那么 KVM acceleration 通常是路径,但 QEMU 仍会塑造机器。[1][3][7]
- 你需要可重复的设备与板级建模吗?那么设备和 machine model 表面就是价值所在,即使它显得冗长。[1][6]
- 你需要编排与生命周期控制吗?那么 QMP 和更高层管理集成就是中心。[4]
- 你需要存储实验、快照或镜像可移植性吗?那么块层和镜像选择就是一等架构问题。[5]
这些都是采用同一项目的不同理由。把它们混成一个泛泛的“VM 用例”,通常会带来松散设计:需要仿真时却假设硬件加速存在,磁盘格式靠习惯选择,管理 API 事后补接,设备模型直到生产里出现差异才被认真看见。
结语
QEMU 能持续存在,是因为它把机器呈现出来。它给操作人员和开发者一组明确的边界:CPU 是翻译还是加速,设备是建模还是直通,控制是通过协议完成,存储依靠定义来抵抗愿望式配置。这会让 QEMU 显得有要求,但这种要求是有生产力的。它要求你说清楚自己正在建造哪一种机器。
对 2026 年使用 QEMU 的团队来说,实际建议很清楚:先写下边界。如果你的用例依赖可移植性,就把 TCG 行为与目标支持写清楚。如果它依赖速度,就记录 accelerator 路径,以及哪些部分仍在 QEMU 用户态。如果它依赖运维,就从一开始围绕 QMP 和管理工具设计。如果它依赖可恢复性,就把磁盘镜像和块后端选择当作架构,放在默认值之前审视。
QEMU 不只是一种运行客户机的方法。它是一种让客户机、宿主机、存储、设备与操作人员之间的契约变得可检查的方法。
来源
- QEMU documentation,"System Emulation: Introduction"。
- QEMU documentation,"Emulation"。
- Linux kernel documentation,"The Definitive KVM (Kernel-based Virtual Machine) API Documentation"。
- QEMU documentation,"QEMU Machine Protocol Specification"。
- QEMU documentation,"Disk Images"。
- QEMU documentation,"Device Emulation"。
- Ubuntu Server documentation,"QEMU"。
- WordPress 托管的 2007 年 Fabrice Bellard 照片。