在银河麒麟ky10 server上编译安装qemu-4.2.0的完整避坑指南(arm/x86通用)
最近在异构计算环境里折腾,想在ARM架构的银河麒麟服务器上跑x86的虚拟机,或者反过来,发现直接通过包管理器安装的QEMU版本功能受限,只能支持同构虚拟化。这就像给你一把只能开自家门的钥匙,想去邻居家串个门都不行。于是,编译安装一个功能完整的QEMU就成了必经之路。我选择的是qemu-4.2.0这个相对稳定且经典的版本,整个过程就像在布满碎石的山路上开车,坑不少,但一一填平后,路就通了。这篇指南就是我的行车记录仪,记录了从环境准备、依赖安装、编译配置到最终验证的完整流程,尤其会聚焦在银河麒麟ky10 server这个特定环境下,无论是ARM还是x86平台,你都能找到对应的解决方案。
1. 环境准备与深度依赖解析
在动手编译之前,把地基打牢至关重要。银河麒麟ky10 server基于开源生态,但其软件仓库的版本和依赖关系有时会有自己的“个性”,直接照搬Ubuntu或CentOS的教程很容易踩坑。
首先,确保你的系统是最新状态。这不是一句空话,因为系统更新可能会解决一些底层库的兼容性问题。执行以下命令进行全量更新:
sudo kylin-update或者使用更通用的yum命令(ky10 server通常兼容):
sudo yum update -y接下来是安装编译工具链。gcc和gcc-c++是核心,但版本匹配很重要。银河麒麟ky10 server默认提供的GCC版本可能不是最新的,但对于qemu-4.2.0来说,通常够用。我们可以先检查一下:
gcc --version g++ --version如果版本过旧(比如低于5.0),你可能需要考虑从源码编译新版本GCC,但这会大大增加复杂度。我的经验是,ky10 server自带的版本编译qemu-4.2.0基本没问题。
注意:编译QEMU是一个资源密集型任务,尤其是内存消耗较大。如果你的服务器内存小于4GB,在
make阶段可能会因内存不足而失败,建议在编译前关闭不必要的服务,或者考虑增加交换空间(swap)。
依赖库的安装是第一个大坑。QEMU的功能模块众多,每个模块都可能依赖特定的开发库。原始文章里给出的依赖列表是一个很好的起点,但不够全面,特别是在异构编译(例如在ARM上编译支持x86的QEMU)时。下面这个更完整的列表,是我结合多次编译经验总结出来的:
- 基础编译工具:
automake,libtool,flex,bison。这些是GNU构建系统(autotools)的必备品,QEMU用它来生成Makefile。 - 核心库:
zlib-devel:压缩库,处理磁盘镜像等压缩数据。glib2-devel(版本 >= 2.48):这是QEMU的核心依赖,提供数据结构、事件循环等基础功能。务必确认版本,版本过低会导致配置失败。pixman-devel:像素操作库,用于图形显示。
- 虚拟化功能支持库:
libaio-devel:异步I/O支持,对磁盘性能至关重要。libusbx-devel或libusb-devel:USB设备直通支持。ncurses-devel或libncurses5-devel:用于QEMU的字符界面(nographic模式)。
- 可选功能库(按需安装):
spice-protocol,spice-server-devel:SPICE桌面协议支持,提供更好的图形体验。usbredir-devel:USB重定向支持。libssh2-devel:支持通过SSH访问磁盘镜像。gtk3-devel,sdl2-devel:GTK和SDL图形显示后端。vte2-devel:GTK终端集成。libpng-devel,libjpeg-turbo-devel:截图等图像功能。
在银河麒麟上,部分软件包名称可能与CentOS/RHEL系略有不同。如果遇到yum找不到包的情况,可以尝试用dnf(如果系统已安装),或者去银河麒麟的官方软件仓库网站查找对应的包名。一个实用的技巧是使用yum search命令,例如:
sudo yum search glib2 | grep devel下表对比了在ARM和x86架构的ky10 server上安装依赖时可能遇到的细微差别:
| 依赖包名 (通用) | ARM平台常见问题 | x86平台常见问题 | 解决方案建议 |
|---|---|---|---|
glib2-devel | 仓库版本可能较旧(如2.56),需确认版本 | 通常版本较新,兼容性好 | ARM平台可尝试从源码编译较新版本的glib2 |
spice-server-devel | 可能依赖的libcacard包在ARM仓库缺失 | 通常完整可用 | 如果不需要SPICE功能,可在配置时用--disable-spice跳过 |
libusbx-devel | 包名可能为libusb-devel | 包名通常为libusbx-devel | 使用yum provides */usb.h查找正确的包名 |
图形后端库 (如gtk3-devel) | 依赖的图形驱动库可能不同 | 依赖关系通常更标准 | 如果仅用于服务器无图形界面,可全部用--disable-*关闭 |
安装命令可以整合为一条,但为了便于排查问题,我建议分组安装:
# 1. 安装基础编译工具 sudo yum install -y gcc gcc-c++ automake libtool flex bison make cmake # 2. 安装核心依赖库 sudo yum install -y zlib-devel glib2-devel glib2-fam pixman-devel libffi-devel # 3. 安装虚拟化增强依赖 sudo yum install -y libaio-devel libcap-devel libcap-ng-devel libattr-devel # 4. 按需安装其他功能库(例如需要网络和图形) sudo yum install -y libslirp-devel gtk3-devel vte2-devel spice-server-devel usbredir-devel完成上述步骤后,你的编译环境才算初步就绪。可以运行pkg-config --list-all | grep -E "(glib|pixman)"来验证关键库的开发文件是否已正确安装。
2. 源码获取与配置的艺术
依赖搞定后,我们开始处理QEMU本身。首先是从官网获取源码。这里有个小坑:download.qemu.org这个域名在某些网络环境下可能连接缓慢或中断。我的建议是,先尝试直接wget,如果速度不理想,可以寻找国内的镜像源,或者先下载到本地再上传到服务器。
# 进入一个工作目录,例如 /opt/src cd /opt sudo mkdir -p src sudo chown $(whoami):$(whoami) src cd src # 下载qemu-4.2.0源码包 wget https://download.qemu.org/qemu-4.2.0.tar.xz # 验证文件完整性(可选但推荐) wget https://download.qemu.org/qemu-4.2.0.tar.xz.sig gpg --verify qemu-4.2.0.tar.xz.sig qemu-4.2.0.tar.xz如果GPG验证失败(因为没有导入QEMU项目的公钥),可以跳过,但最好通过对比SHA256校验和来确保文件未损坏。官网通常会提供校验和文件。
解压源码包:
tar xvJf qemu-4.2.0.tar.xz cd qemu-4.2.0现在来到最关键的一步:./configure。这是决定编译成败和最终QEMU功能集的核心环节。原始文章里直接运行./configure采用了所有默认配置,这在很多情况下会导致编译失败,或者编译出的二进制文件缺少关键功能(比如缺少对非本机架构的模拟支持)。
配置的目标是:在ARM主机上,编译出一个既能模拟ARM(KVM加速),也能模拟x86(TCG解释执行)的QEMU;反之亦然。
下面是我经过多次试验后,在银河麒麟ky10 server上(以ARM平台为例)推荐的基础配置命令:
./configure \ --target-list=aarch64-softmmu,x86_64-softmmu \ --audio-drv-list= \ --disable-gtk \ --disable-sdl \ --disable-virtfs \ --disable-xen \ --enable-linux-aio \ --enable-kvm \ --enable-virtfs \ --prefix=/usr/local/qemu-4.2.0让我逐一解释这些参数的含义和背后的“坑”:
--target-list=aarch64-softmmu,x86_64-softmmu:这是实现异构虚拟化的灵魂参数。它指定了要编译哪些目标架构的模拟器。aarch64-softmmu对应ARM 64位系统模拟,x86_64-softmmu对应x86 64位系统模拟。你可以根据需要添加更多,如arm-softmmu(32位ARM)、i386-softmmu(32位x86)等。但每增加一个目标,编译时间都会显著增加。--audio-drv-list=:设置为空,禁用所有音频驱动。在无图形界面的服务器上,音频支持通常不需要,而且其依赖复杂,容易引起编译错误。--disable-gtk --disable-sdl:禁用GTK和SDL图形界面。对于纯命令行管理的服务器环境,这些图形后端非必需,且它们的依赖库(如GTK3)在服务器最小化安装时可能不完整。--enable-kvm:启用KVM(基于内核的虚拟机)加速。这是性能关键!它允许QEMU使用宿主机的硬件虚拟化扩展(如ARM的KVM或x86的Intel VT-x/AMD-V)来加速与本机架构相同的虚拟机。例如,在ARM主机上运行ARM虚拟机时,性能接近原生。但请注意,KVM无法用于加速异构模拟(如在ARM上跑x86),那时会回退到纯软件模拟(TCG)。--prefix=/usr/local/qemu-4.2.0:指定安装路径。我强烈建议不要安装到默认的/usr/local,而是用一个带版本号的子目录。这样你可以同时安装多个QEMU版本,并通过修改PATH环境变量来切换,避免污染系统目录。
执行./configure命令后,请务必仔细阅读输出结果。它会打印一个详细的摘要,告诉你哪些功能被启用(yes),哪些被禁用(no),以及原因(通常是依赖未找到)。这是排查问题的最佳时机。
常见的配置错误及解决:
ERROR: glib-2.48 gthread-2.0 is required to compile QEMU
提示:这是最常见的错误,意味着系统安装的glib2开发库版本低于2.48。银河麒麟仓库的版本有时确实偏低。解决方法是从源码编译安装新版本glib2。先去官网下载2.48或更高版本的源码,编译安装到自定义目录(如
/opt/glib-2.68),然后在配置QEMU时通过PKG_CONFIG_PATH环境变量指定新版本的位置:export PKG_CONFIG_PATH=/opt/glib-2.68/lib/pkgconfig:$PKG_CONFIG_PATH ./configure ... # 你的其他参数ERROR: pixman not found
提示:确保安装了
pixman-devel包。如果已安装但仍报错,可能是pkg-config找不到它。尝试用yum install pixman-devel重装,或者手动指定路径。WARNING: Cannot find 'nasm' / 'iasl'
提示:这些是编译某些x86相关组件(如UEFI固件)所需的工具。对于异构编译(在ARM上编译x86目标),
nasm(汇编器)是必须的。安装它:sudo yum install -y nasm。iasl(ACPI编译器)通常不是必须,警告可以忽略。
配置成功后的输出末尾应该类似于:
... QEMU 4.2.0 configure summary --- target list aarch64-softmmu x86_64-softmmu ... KVM support yes ... Install prefix /usr/local/qemu-4.2.0 ...确认你的目标架构(target list)和KVM支持(如果主机支持)都是yes。
3. 编译、安装与疑难排错
配置通过后,就可以开始编译了。这一步相对简单,但耗时较长,且可能遇到编译器错误。
使用make命令开始编译,建议使用-j参数指定并行编译的作业数,以充分利用多核CPU,大幅缩短时间。作业数通常设置为CPU核心数的1到2倍。你可以用nproc命令查看核心数:
# 假设是8核CPU make -j8编译过程可能会持续十几分钟到半小时以上,取决于你的服务器性能。在这个过程中,你可能会遇到以下几种典型的编译错误:
错误:
fatal error: 'XXX.h' file not found这通常是头文件找不到,意味着某个开发库虽然安装了,但它的头文件路径没有被编译器找到。首先确认对应的devel包是否已安装(如error: 'libusb.h' not found对应libusbx-devel)。如果已安装,可能是路径非标准。你可以尝试在编译命令中通过CFLAGS和LDFLAGS环境变量指定搜索路径,但更根本的方法是确保通过系统包管理器安装的库能被pkg-config正确找到。错误:
undefined reference to 'function_name'这是链接错误,表明编译器找到了头文件,但链接时找不到对应的库文件(.so或.a)。原因可能是:- 开发库安装了,但运行时库没安装(不过
devel包通常依赖运行时库)。 - 库文件版本不对。
- 库的安装路径不在默认的链接器搜索路径中。 解决方法类似于头文件问题,确保
-devel包安装,并检查/usr/lib64或/usr/lib下是否存在对应的.so文件。
- 开发库安装了,但运行时库没安装(不过
错误:
internal compiler error: Killed (program cc1)这通常是因为编译过程中内存耗尽,系统杀死了编译器进程。在资源有限的虚拟机上尤其常见。解决方法:- 减少并行编译作业数:
make -j2或直接make(单线程)。 - 增加交换空间(Swap)。
- 关闭其他占用内存的进程。
- 减少并行编译作业数:
如果遇到难以解决的编译错误,一个“终极”但有效的方法是回到configure阶段,禁用掉所有非必需的功能模块,特别是那些依赖复杂外部库的模块(如SPICE、GTK、VNC以外的图形后端等)。一个最小化配置可能如下:
./configure --target-list=x86_64-softmmu --disable-gtk --disable-sdl --disable-vnc --disable-spice --disable-usb-redir --disable-libssh2 --prefix=/usr/local/qemu-minimal先编译通过一个能用的版本,再逐步启用所需功能。
编译成功后,进行安装:
sudo make install这会将编译好的二进制文件、库文件、文档等安装到之前--prefix指定的目录(例如/usr/local/qemu-4.2.0)。
安装完成后,为了方便使用,建议将QEMU的二进制文件路径添加到系统的PATH环境变量中。编辑你的shell配置文件(如~/.bashrc或~/.bash_profile):
echo 'export PATH=/usr/local/qemu-4.2.0/bin:$PATH' >> ~/.bashrc source ~/.bashrc然后验证安装是否成功,并查看支持的架构:
qemu-system-x86_64 --version qemu-system-aarch64 --version这两个命令应该能正确输出QEMU的版本信息。如果提示命令未找到,请检查PATH设置和安装路径。
4. 验证与基础使用:让虚拟机跑起来
安装完成不是终点,让虚拟机真正运行起来才是。这里我们分别验证在ARM主机上运行x86虚拟机,以及在x86主机上运行ARM虚拟机的基本流程。我们以创建一个简单的、使用TCG软件模拟的虚拟机为例。
场景一:在ARM架构的银河麒麟ky10 server上运行一个x86_64 Linux虚拟机
准备虚拟磁盘:
# 创建一个10GB的qcow2格式虚拟磁盘文件 qemu-img create -f qcow2 x86_vm_disk.qcow2 10Gqcow2是QEMU推荐的动态分配格式,一开始只占用很少的物理空间。准备安装镜像:下载一个x86_64架构的Linux安装ISO,例如Alpine Linux或一个小型的发行版,以节省时间和资源。
wget https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/x86_64/alpine-standard-3.18.0-x86_64.iso启动安装:使用QEMU启动虚拟机,挂载安装镜像。由于是异构模拟(ARM模拟x86),我们无法使用KVM加速,必须使用纯软件模拟的TCG。
qemu-system-x86_64 \ -machine accel=tcg \ -m 2048 \ -smp 2 \ -cdrom alpine-standard-3.18.0-x86_64.iso \ -drive file=x86_vm_disk.qcow2,format=qcow2 \ -boot d \ -nographic \ -serial mon:stdio参数解释:
-machine accel=tcg:显式指定使用TCG加速器(软件模拟)。如果不指定,QEMU会尝试寻找KVM,但在异构环境下会失败。-m 2048:分配2GB内存给虚拟机。-smp 2:分配2个虚拟CPU核心。-cdrom ...:指定安装光盘镜像。-drive file=...:指定虚拟硬盘。-boot d:从光盘(d:)启动。-nographic -serial mon:stdio:这两个参数组合,将QEMU输出重定向到当前终端,适用于无图形界面的服务器环境。你可以通过按Ctrl+A,然后按C来进入QEMU监视器。
后续启动:安装完成后,后续启动虚拟机就不需要
-cdrom和-boot d参数了:qemu-system-x86_64 -machine accel=tcg -m 2048 -smp 2 -drive file=x86_vm_disk.qcow2,format=qcow2 -nographic -serial mon:stdio
场景二:在x86架构的银河麒麟ky10 server上运行一个AArch64 ARM虚拟机
流程完全类似,只是目标架构和镜像换成了ARM。
准备ARM虚拟磁盘和镜像:
qemu-img create -f qcow2 arm_vm_disk.qcow2 10G wget https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/aarch64/alpine-standard-3.18.0-aarch64.iso启动安装:使用
qemu-system-aarch64命令。qemu-system-aarch64 \ -machine virt,accel=tcg \ -cpu cortex-a57 \ -m 2048 \ -smp 2 \ -cdrom alpine-standard-3.18.0-aarch64.iso \ -drive file=arm_vm_disk.qcow2,format=qcow2 \ -boot d \ -nographic \ -serial mon:stdio注意参数变化:
-machine virt,accel=tcg:对于ARM虚拟机,我们使用virt这个通用的虚拟平台,并指定TCG加速。-cpu cortex-a57:指定模拟的CPU型号。virt平台支持多种CPU型号,cortex-a57是一个常见的选择。
提示:在异构模拟(TCG)模式下,性能会远低于原生(KVM)模式。它更适合于测试、软件移植或运行轻量级负载。对于生产级性能需求,应尽可能使用同构虚拟化(KVM)。
网络配置(进阶):上面的例子使用了最简单的用户模式网络(-netdev user的默认行为),虚拟机可以访问外网,但宿主机无法直接访问虚拟机。对于更复杂的网络需求,如桥接网络,需要宿主机系统的额外配置(创建网桥、配置防火墙等),这超出了本文基础指南的范围,但它是构建可用虚拟化环境的关键一步。
最后,别忘了你安装的QEMU路径是自定义的。当你尝试使用像libvirt(virt-manager的后端)这样的高级管理工具时,需要确保它们能找到你的QEMU二进制文件。你可能需要修改libvirt的配置文件(/etc/libvirt/qemu.conf),指定qemu_path,或者直接使用绝对路径来调用你编译的QEMU。