3. QEMU源码编译:从源码编译QEMU、配置目标架构与常见错误处理
说实话,很多做嵌入式Linux的朋友一开始都习惯直接 apt install qemu-system-arm。但当你需要定制QEMU特性、打补丁、或者调试QEMU自身行为时,从源码编译就成了绕不开的一步。我个人习惯在项目初期就把QEMU源码环境搭好,后面做板级仿真、外设模拟会顺手很多。
3.1 为什么非要自己编译QEMU?
你可能会问:包管理器装的不香吗?嗯,这里有几个场景,包管理器搞不定:
- 定制目标架构:默认包只编译了常见架构,你想模拟某个冷门开发板?得自己来。
- 打补丁调试:我在项目中遇到过QEMU模拟某款网卡时丢包,需要加调试打印,必须从源码编译。
- 版本锁定:团队统一用QEMU 8.2.0,但Ubuntu源里只有7.2,源码编译最稳。
- 性能优化:开启TCG加速、调整内存模型,这些编译选项包管理器给不了你。
3.2 编译前的准备:依赖与源码获取
先别急着 git clone,依赖没装全的话,编译到一半报错会让你抓狂。我踩过这个坑,所以列个清单给你:
| 依赖类别 | 关键包名(Ubuntu/Debian) | 说明 |
|---|---|---|
| 基础编译工具 | build-essential, pkg-config, meson, ninja-build | Meson是QEMU 6.0+的构建系统,必须装 |
| 图形/显示 | libsdl2-dev, libgtk-3-dev, libvte-dev | 没有这些,你只能跑无头模式(-nographic) |
| 网络支持 | libslirp-dev, libpcap-dev | 用户态网络和桥接网络需要 |
| 虚拟化加速 | libvirglrenderer-dev, libdrm-dev | 开启KVM加速时用 |
| 文档/测试 | python3-sphinx, texinfo | 编译文档时需要,可跳过 |
装依赖的命令很简单:
sudo apt update
sudo apt install build-essential pkg-config meson ninja-build \
libsdl2-dev libgtk-3-dev libvte-dev \
libslirp-dev libpcap-dev \
python3-sphinx texinfo
apt install 打断思路。如果你磁盘空间紧张,可以只装基础+目标架构需要的依赖。
源码获取,我推荐用官方git仓库,方便切换版本:
git clone https://gitlab.com/qemu-project/qemu.git
cd qemu
git checkout v8.2.0 # 锁定稳定版本
3.3 配置目标架构:configure与Meson选项
QEMU的配置系统从6.0开始全面转向Meson。但入口还是 configure 脚本,它会调用Meson做实际工作。说白了,你只需要跟 configure 打交道。
配置的核心是 --target-list 参数。默认编译所有架构,耗时很长。我建议只选你需要的:
./configure --target-list=arm-softmmu,aarch64-softmmu,riscv64-softmmu \
--enable-slirp \
--enable-kvm \
--enable-debug \
--prefix=/opt/qemu-8.2
解释一下关键选项:
- --target-list:指定目标架构。格式是
架构-软MMU(系统模式)或架构-linux-user(用户模式)。 - --enable-slirp:开启用户态网络,仿真时虚拟机可以直接上网。
- --enable-kvm:宿主机支持KVM时,开启硬件加速。
- --enable-debug:保留调试符号,方便后续用GDB调试QEMU本身。
- --prefix:安装路径,避免污染系统目录。
常见的架构后缀对照表:
| 目标架构 | 系统模式(softmmu) | 用户模式(linux-user) | 典型用途 |
|---|---|---|---|
| ARM 32位 | arm-softmmu | arm-linux-user | STM32MP1、Cortex-A系列 |
| AArch64 | aarch64-softmmu | aarch64-linux-user | 树莓派4、Raspberry Pi OS |
| RISC-V 64位 | riscv64-softmmu | riscv64-linux-user | SiFive Unleashed、OpenSBI |
| x86_64 | x86_64-softmmu | x86_64-linux-user | PC仿真、KVM测试 |
softmmu。
3.4 编译与安装
配置成功后,Meson会生成构建目录(默认在 build/)。编译命令很简单:
make -j$(nproc) # 并行编译,充分利用CPU核心
我第一次编译QEMU 8.2时,只选了三个架构,大概花了15分钟。如果全架构编译,半小时起步。你可以去喝杯咖啡。
编译完成后,安装到指定目录:
sudo make install
验证安装:
/opt/qemu-8.2/bin/qemu-system-aarch64 --version
如果看到版本号输出,恭喜你,编译成功。
3.5 常见编译错误与避坑指南
编译QEMU很少一帆风顺。我把自己遇到过的典型错误整理出来,你遇到了直接对照解决。
错误1:Meson版本过低
现象:configure 报错 Meson version 0.61.0 or higher required。
原因:系统自带的Meson太老。Ubuntu 20.04默认是0.53,不够用。
解决:
pip3 install --upgrade meson
# 或者用pip3安装最新版
pip3 install meson==1.2.0
meson --version 看一眼。
错误2:缺少glib-2.56
现象:configure 报错 glib-2.56 >= 2.56 is required。
原因:系统glib库版本太低。老发行版常见。
解决:
sudo apt install libglib2.0-dev
# 如果还不行,手动编译glib或升级系统
错误3:Python3路径不对
现象:configure 报错 Python not found 或 Python version too old。
原因:系统默认python指向python2,或者python3没装。
解决:
sudo apt install python3 python3-pip
# 指定python3路径
./configure --python=/usr/bin/python3
错误4:编译时链接失败(undefined reference)
现象:make 过程中出现大量 undefined reference to 'xxx'。
原因:通常是某个依赖库没装,或者版本不匹配。
解决:
- 检查
configure输出,看哪些feature被标记为NO。 - 安装对应的
-dev包。 - 清理构建目录重新配置:
rm -rf build/然后重新./configure。
错误5:KVM权限问题
现象:编译成功,但运行时报错 Could not access KVM kernel module: Permission denied。
原因:当前用户不在 kvm 用户组。
解决:
sudo usermod -aG kvm $USER
# 重新登录或执行 newgrp kvm
3.6 知识体系:QEMU编译流程全景
下面这张图帮你理清整个编译流程的脉络:
3.7 进阶技巧:定制化编译
如果你需要更精细的控制,这里有几个实用技巧:
- 只编译特定设备:通过
--with-devices选项指定,比如只编译virt开发板:--with-devices=arm-virt。 - 开启TCG调试:
--enable-tcg-interpreter可以单步跟踪每条指令的翻译过程,调试内核时很有用。 - 静态编译:
--static选项生成静态链接的QEMU,方便移植到其他环境。 - 交叉编译:如果你想在x86上编译ARM架构的QEMU,需要设置交叉工具链:
--cross-prefix=arm-linux-gnueabihf-。
arm-softmmu 和 aarch64-softmmu,再加一个 riscv64-softmmu 做对比测试。够用就好,别贪多。