Linux 安装 QEMU:apt 与 dnf 两系发行版装齐 system、user 态与工具链
在 Linux 上装 QEMU,最容易踩的坑不是命令本身,而是包名在两大包管理体系里几乎不通用。Debian/Ubuntu 用 apt,QEMU 被拆成 qemu-system、qemu-user、qemu-utils 等一组语义清晰的小包;RHEL/Rocky 用 dnf(旧称 yum),主程序包叫 qemu-kvm,二进制还不在常规的 PATH 目录里。照着 Ubuntu 的教程去 Rocky 上敲 dnf install qemu-system,只会得到一句「没有匹配的包」。如果你还不清楚 QEMU 的 system 态和 user 态到底是什么关系,先读 QEMU system 模式与 user 模式:全系统模拟和用户态转译的分工建立概念,本篇聚焦「怎么装齐、怎么核验、装错了怎么救」。
本篇的所有命令都在两台云主机上真跑过:一台 Ubuntu 22.04.5 走 apt,装到的 QEMU 版本是 6.2.0;一台 Rocky Linux 9 走 dnf,装到的是 10.1.0。两个版本差距不小,这正是从发行版仓库安装 QEMU 的固有特征——版本由发行版冻结,不随上游同步。对虚拟机、镜像这些基本概念还陌生的读者,可以先看 认识 QEMU:从零看懂虚拟机、镜像与快照。
本文要回答的问题
- 一套能做 SoC 实验的 QEMU 环境,到底由哪几类组件构成,只装一个
qemu-system为什么不够? - apt 系的
qemu-system、qemu-user、qemu-utils、device-tree-compiler各自提供什么? - dnf 系为什么找不到
qemu-system这个包,qemu-kvm和/usr/libexec/qemu-kvm是怎么回事? - 安装单里写错一个包名,dnf 为什么会把整单全部回滚、一个包都不装?
- 装完之后用哪几条命令确认四类组件确实可用、版本对得上?
一、QEMU 不是一个程序:先认四大组件
很多人以为「安装 QEMU」就是装一个模拟器,实际上下一篇篇实验做下来,你会接触到四类彼此独立的组件。第一类是 system 态模拟器,即 qemu-system-<架构> 系列二进制,它模拟整台机器(CPU、内存、中断控制器、外设),能跑完整客户机操作系统,是后续 RISC-V virt 虚拟平台实验的主力。第二类是 user 态转译器,即 qemu-<架构> 系列(如 qemu-riscv64),它不模拟整机,只转译单个可执行文件的指令,让你在 x86 主机上直接运行另一种架构的 Linux 程序。第三类是镜像工具,核心是 qemu-img,负责创建、转换、扩容 qcow2/raw 磁盘镜像。第四类是设备树与固件:dtc(device-tree-compiler)编译设备树源码,OpenSBI、U-Boot 等固件包提供 RISC-V 虚拟机的启动载荷。
这四类组件在 apt 系里是分开的包,在 dnf 系里拆分粒度又不同,所以安装前先想清楚「我要哪几类功能」,再去对应仓库里挑包,比照着一条来历不明的命令全盘复制可靠得多。下面这张流程卡是本篇的主线:从认组件到查包名、组安装单、核验,再到失败时的回退纠正。
读这张卡抓住一条原则:第 2 步「查真实包名」是两系发行版最大的分叉点,也是本篇第四节那次失败的根源。apt 系的包名贴近上游功能名,dnf 系则带着 RHEL 的虚拟化产品烙印,不能想当然互换。
二、apt 系实操:一条安装单装齐 Ubuntu 上的 QEMU
Ubuntu 22.04 的 universe 仓库里,QEMU 6.2 系列被拆成约二十个小包。先更新索引,再按四大组件分组把包装齐:
sudo apt update
sudo apt install -y \
qemu-system qemu-system-misc \
qemu-user qemu-user-static \
qemu-utils \
device-tree-compiler opensbi u-boot-qemu各包的分工如下。qemu-system 是元包,按依赖把 qemu-system-x86、qemu-system-arm、qemu-system-misc(含 RISC-V 等小众架构)等整组模拟器拉进来;只装它而不装 qemu-system-misc,在某些精简镜像上会缺 qemu-system-riscv64。qemu-user 提供动态链接版的用户态转译器,qemu-user-static 提供静态版本并注册 binfmt 钩子,装完后可以直接执行外来架构的 ELF 文件。qemu-utils 里最常用的是 qemu-img。device-tree-compiler 提供 dtc 命令;opensbi 与 u-boot-qemu 是 RISC-V 虚拟机的 S 态固件与引导加载器,做裸机或 Linux 启动实验时缺一不可。
两个 apt 侧的查询习惯值得养成。一是装前用 apt-cache policy qemu-system 看候选版本与来源仓库,确认 universe 仓库已经启用、候选版本就是发行版快照里的那一版;二是遇到「某个命令该装哪个包」的疑问时,用 dpkg -S $(which qemu-img) 反查文件归属,会看到 qemu-utils: /usr/bin/qemu-img 这样的答案,比在搜索结果里猜包名可靠。配合 apt-cache depends qemu-system 还能展开元包的完整依赖树,看清 qemu-system-x86、qemu-system-arm、qemu-system-misc 是怎么被一条命令拉进来的——理解了这层元包机制,就能解释为什么最小化容器镜像里只装 qemu-system 有时会缺架构,问题往往出在推荐依赖被 --no-install-recommends 裁掉。
下面是本次安装的真实终端实录,前半段是仓库里全部 QEMU 相关包及其冻结版本,后半段是三条核验命令的输出。
读这段实录盯住三个位置。包清单里 qemu-system、qemu-system-arm、qemu-system-misc 等全部落在同一个版本串 1:6.2+dfsg-2ubuntu6.31 上,说明 apt 把整组 QEMU 包作为同一发行版快照维护,不会出现组件版本错位;qemu-user 与 qemu-user-static 版本号相同,两类转译器来自同一源码包。末尾三条版本命令分别核验了 system 态(QEMU emulator version 6.2.0)、user 态(qemu-riscv64 version 6.2.0)和镜像工具(qemu-img version 6.2.0),三类组件全部可执行,安装才算闭环。另外注意 device-tree-compiler 的版本是 1.6.1-1,它有自己独立的发布节奏,并不与 QEMU 版本同步。
三、dnf 系实操:RHEL/Rocky 的包名是另一套语言
切到 Rocky Linux 9,第一件事是承认 apt 的包名经验全部失效。这里不要急着安装,先用 dnf search 看仓库到底提供什么:
dnf search qemu实录节选的九个包里,主角是 qemu-kvm——RHEL 系把 QEMU 与 KVM 加速深度绑定后用了这个名字,描述写的是「machine emulator and virtualizer」,它就是 system 态模拟器的主包;qemu-kvm-common 是所有目标架构共用的公共文件,用户态转译等能力随这一组依赖落地;qemu-img 在这里是独立包,不像 apt 那样收在 qemu-utils 里。最小可用安装单因此非常短:
dnf install -y qemu-kvm qemu-img实录显示事务正常收尾,末尾打印 Complete!。但装完有个反直觉的地方:敲 qemu-system-x86_64 会提示命令不存在,因为 RHEL 系的主程序路径是 /usr/libexec/qemu-kvm,不在普通用户的默认 PATH 里。核验版本要带上完整路径,镜像工具则正常挂在 /usr/bin/qemu-img:
这段实录有两个值得对比的数字。其一是版本:qemu-img version 10.1.0 与 /usr/libexec/qemu-kvm 的 QEMU emulator version 10.1.0 同属 qemu-kvm-10.1.0-17.el9_8.9 发行版构建,比 Ubuntu 22.04 的 6.2.0 领先了四个大版本——同一名为「仓库安装」,两系拿到的代际差距可以非常大,追求新特性时要把发行版冻结策略考虑进去。其二是主程序体积,ls -l 显示 /usr/libexec/qemu-kvm 约 32 MB,这个单体二进制聚合了多架构模拟能力,与 apt 系按架构拆成一堆 qemu-system-* 小二进制的组织方式形成鲜明对照。设备树编译器在 dnf 系叫 dtc,需要时执行 dnf install -y dtc 另装;RISC-V 固件则随虚拟化组件的依赖链落地,没有 apt 系那样独立的 opensbi 包名。
四、一次真实失败:错误包名让整单事务中止
本次 dnf 实验保留了一次有教学价值的失败。最初的安装单里混入了一个从其他发行版教程抄来的包名 qemu-device-display-virtio-gpu——这种细粒度的显示设备拆包命名存在于部分上游和别的发行版体系里,但 Rocky 9 的仓库中并没有这个包。dnf 在依赖解析阶段直接报「没有匹配的参数」(No match for argument),并以「无法找到匹配」结束,整个安装事务中止,一个包都不会落地,包括本来写对了的 qemu-kvm 和 qemu-img。
这是 dnf 与 apt 行为差异里最容易让人慌的一点。apt 遇到无法定位的包会明确跳过它、继续安装其余包;dnf 的安装是原子事务,解析期任何一个参数无法满足,整单回滚,系统保持安装前状态。这种设计避免了「装了一半」的残缺环境,但也意味着你必须先把包名全部查准。纠正过程分两步:先 dnf search qemu 拿到仓库里的真实包名清单(即第三节实录开头的节选),确认显示设备相关能力已经收在 qemu-kvm 主包及其依赖里、无需单独安装;再把安装单收敛为最小可用集合 qemu-kvm qemu-img 重新执行,事务随即 Complete!。把这条经验推广开:任何 dnf install 报「Unable to find a match」,都不要尝试加 --skip-broken 硬闯,而是回到 search 核对包名,拆单验证后再装。
五、两系包组关系全景:一张图看懂命名映射
把前四节的包名与组件关系压进一张关系图。顶层是四大功能需求,向下分成 apt 与 dnf 两个发行版容器,容器内每个色块对应一类组件的实际包名与落地形态。
读图时按颜色横向对齐:蓝色是 system 态整机模拟,紫色是 user 态转译,橙色是镜像工具,绿色是设备树与固件。同色的两个色块功能等价、包名不同,这张图本身就是一份两系翻译表。最需要记住的两个不对称:apt 的 qemu-img 藏在 qemu-utils 里,dnf 系它是独立包;apt 的固件是 opensbi、u-boot-qemu 两个独立包,dnf 系没有同名物,跟着主包依赖走。
表格把图里装不下的版本与路径细节补齐,实际排错时查表比翻图快。
| 维度 | apt(Ubuntu 22.04) | dnf(Rocky 9) |
|---|---|---|
| system 主包 | qemu-system 元包,按架构拆 qemu-system-x86/arm/misc | qemu-kvm 单体主包 |
| 主程序路径 | /usr/bin/qemu-system-<架构> | /usr/libexec/qemu-kvm |
| user 态转译 | qemu-user、qemu-user-static 独立包 | 随 qemu-kvm-common 等依赖落地 |
| 镜像工具 | qemu-utils(内含 qemu-img) | qemu-img 独立包 |
| 设备树编译器 | device-tree-compiler,实测 1.6.1 | 包名 dtc,按需另装 |
| RISC-V 固件 | opensbi、u-boot-qemu 独立包 | 随主包依赖链落地 |
| 实测版本 | 6.2.0(1:6.2+dfsg-2ubuntu6.31) | 10.1.0(qemu-kvm-10.1.0-17.el9_8.9) |
| 包名错误时 | 跳过坏包、继续装其余包 | 整单事务回滚,一个不装 |
六、装完之后的核验三板斧与下一步
无论哪一系,安装收尾都用同一组思路核验,区别只在二进制路径。第一板斧查版本:apt 系直接 qemu-system-riscv64 --version、qemu-riscv64 --version,dnf 系用 /usr/libexec/qemu-kvm --version,看到版本串与发行版构建号即正常。第二板斧查镜像工具:qemu-img --version 能打印版本,再顺手 qemu-img info 一个已有 qcow2 文件确认子命令齐全。第三板斧查设备树与固件:dtc --version 确认编译器在位,RISC-V 实验前再到 /usr/lib/riscv64-linux-gnu/opensbi/(apt)这类发行版约定目录确认固件文件存在。apt 系装了 qemu-user-static 的机器还可以补第四项检查:cat /proc/sys/fs/binfmt_misc/qemu-riscv64 应能看到 binfmt 注册项与 flags: F 标志,意味着内核遇到 RISC-V ELF 会自动调用静态转译器,直接 ./hello-riscv64 即可运行;这个文件不存在,多半是 binfmt 服务未启用或只装了动态版 qemu-user。三板斧(或四板斧)全部通过,才进入创建镜像、启动第一台虚拟机的环节。
两系安装的关键证据可以对照着看:apt 清单里整组包共享 6.2+dfsg-2ubuntu6.31 版本串,三条版本命令分别报出 6.2.0;dnf 搜索结果以 qemu-kvm 为主包,安装事务收尾于 Complete!,核验段给出 10.1.0 与 /usr/libexec/qemu-kvm 的 32 MB 单体路径,中间还能看到错误包名被拒后事务中止、改单重跑的转折。
对照两份实录看两系差异会非常直观:apt 一侧是「一排同版本号的小包」,dnf 一侧是「一个主包加少量独立工具」;版本数字 6.2.0 与 10.1.0 的落差、/usr/bin 与 /usr/libexec 的路径落差,都解释了为什么同一份教程不能跨发行版照搬。环境就绪后,下一篇 从零安装第一台 RISC-V virt 虚拟机 会用这里装好的 qemu-system-riscv64、OpenSBI 与 qemu-img 走完创建镜像到开机登录的全流程;想先理解 user 态那条线,则回到 QEMU system 模式与 user 模式:全系统模拟和用户态转译的分工。
实验环境
- 机器/系统:云主机 2C8G,分别安装 Ubuntu 22.04.5 LTS(apt)与 Rocky Linux 9(dnf)
- 工具版本:apt 系 QEMU 6.2.0(
1:6.2+dfsg-2ubuntu6.31)、device-tree-compiler 1.6.1;dnf 系 QEMU 10.1.0(qemu-kvm-10.1.0-17.el9_8.9) - 日期:2026-11-08
- 完整命令序列:apt 侧执行包清单查询、四大组件安装与三条
--version核验;dnf 侧先dnf search qemu取真实包名,复现错误包名导致的事务中止,再以qemu-kvm qemu-img最小集合重装并核验版本与主程序路径,全部输出分别留存为run-apt.log与run-dnf.log。
代码获取:本篇两系安装与核验的可复现脚本见公开仓库 derekzhuo/geek-doc.cn 的
experiments/qemu-install-linux-distro目录。克隆后在对应发行版上执行./run-apt.sh或./run-dnf.sh,输出与本篇引用的两份实录逐条对应,目录内 README 附有两系包组差异对照表。
这一篇在知识体系里的位置
本篇是 SoC 与 QEMU 入门路线的环境准备篇,回答「工具从哪来、装得对不对」。组件概念的上游是 QEMU system 模式与 user 模式:全系统模拟和用户态转译的分工,虚拟机与镜像的基础图景见 认识 QEMU:从零看懂虚拟机、镜像与快照;环境核验通过后的自然下一步是 从零安装第一台 RISC-V virt 虚拟机,把本篇装好的模拟器、固件与 qemu-img 串成一次完整开机。再往后,客户机上网、主机端口转发、串口控制台接线等主题都会默认你已经拥有这套经过核验的两系环境。
总结
Linux 安装 QEMU 的关键不在命令而在包名体系:apt 系按功能拆成 qemu-system、qemu-user、qemu-utils 与 device-tree-compiler 等小包,固件走 opensbi、u-boot-qemu 独立包;dnf 系以 qemu-kvm 为主包、主程序落在 /usr/libexec/qemu-kvm,qemu-img 独立、dtc 按需另装,user 态能力随公共依赖落地。实测两系版本分别为 6.2.0 与 10.1.0,体现发行版冻结策略的代际差。dnf 对错误包名实行原子事务、整单回滚,处置方法是回到 dnf search 核对真实包名后收敛安装单,而非加参数硬闯。装完用版本、镜像工具、设备树固件三板斧核验,再进入第一台 RISC-V 虚拟机的实战。