☰
QEMU 跨架构模拟实战:从 x86 到 ARM64 的虚拟机搭建指南
2026/10/8 3:31:59 网站建设 项目流程

当初第一次在 x86 机器上跑qemu-system-aarch64,看着屏幕上弹出 ARM64 版 Alpine 的安装界面,我是真有点兴奋的。后来又在 Windows 上拿 QEMU 装 openEuler 的 ARM 虚拟机,再后来干脆在手机 Termux 里折腾 QEMU,一路下来踩的坑比学的命令还多。如果你正在搜“qemu 操作”,大概率也是想搞清楚:怎么装、怎么启动、怎么跑 ARM64 系统、怎么在 Windows 或手机上用。这篇就把我实际验证过的流程和教训全部写出来,按场景给命令、给参数、给排查思路,你照着操作基本能一次跑通。

1. 先分清 QEMU 的两种工作模式,别等装完才发现用错了

很多人把 QEMU 理解成“虚拟机软件”,这个说法不算错,但会误导你的使用方式。QEMU 实际上分两条完全不同的路线:全系统模拟和用户态模拟。它们对应的命令不一样、应用场景不一样,连安装包都经常是分开的。

1.1 全系统模拟:把一整台机器演出来

我们平时说的qemu-system-x86_64、qemu-system-aarch64属于全系统模拟。它直接模拟一整台电脑:CPU、内存、主板芯片组、硬盘控制器、网卡、显卡、USB 控制器……客户机操作系统根本不知道自己跑在虚拟机里,它会像在真机上一样做硬件探测、加载驱动。

你可以用它做这些事:

  • 在同一台 x86 电脑上运行 ARM64 版本的 Linux 发行版,比如 openEuler、Alpine、Debian 的 aarch64 镜像;
  • 在没有 GUI 的服务器上跑一个纯命令行虚拟机做测试;
  • 调试内核、交叉编译后的镜像,因为你可以完全控制机器参数;
  • 模拟嵌入式设备的环境,比如 ARM 开发板。

全系统模拟的代价是性能开销大。CPU 每条指令都要经过翻译,后面我会详细讲。

1.2 用户态模拟:只翻译单个程序

另一条路线是用户态模拟,对应命令是qemu-aarch64、qemu-arm、qemu-x86_64这类不带-system的。它只模拟一个 CPU 和 Linux 的系统调用接口,用来直接运行单个可执行文件,不模拟整机。

典型用法是:

# 在 x86 Linux 上直接运行 ARM64 的二进制文件 qemu-aarch64-static ./my_arm64_program # 配合 binfmt_misc,可以直接执行 ARM 架构的程序 sudo update-binfmts --enable qemu-aarch64

做嵌入式开发的人经常用它跑交叉编译产物,或者配合 Docker 在 x86 上构建多架构镜像。日常折腾虚拟机一般用不到用户态模式,但你得知道区别,否则找错命令很容易一脸懵。

1.3 TCG、KVM 和硬件加速到底怎么回事

QEMU 默认的翻译执行引擎叫 TCG(Tiny Code Generator),它是一种动态二进制翻译器:把客户机的 ARM 指令实时翻译成宿主机的 x86 指令。好处是跨架构也能跑,坏处是慢,通常比原生慢一个数量级以上。

如果想提速,需要硬件辅助虚拟化,这时候就要分清加速器:

加速器所在平台能不能跨架构
KVMLinux只能同架构,x86 宿主机只能加速 x86 客户机
HVFmacOS一般只用于 x86 / x64 客户机
WHPXWindows同样只能加速 x86 客户机
TCG所有平台可以模拟任意架构,但无硬件加速

这里有个很容易误解的点:很多人以为在 x86 电脑上用 KVM 就能“加速模拟 ARM64”,不能。KVM 是让 CPU 直接运行客户机的同架构指令,ARM64 指令在 x86 CPU 上根本无法直接执行,所以跨架构模拟只能走 TCG。你会在 x86 上跑qemu-system-aarch64时看到它默认用 TCG,这是正常的,别去折腾 KVM 了。

明白了这个底层逻辑,后面遇到“为什么这么慢”“为什么 KVM 用不了”之类的问题,你自己就能判断了。

2. 装好 QEMU 之后,第一台虚拟机该怎么拉起来

我建议别一上来就玩 ARM64,先在你本机架构上跑通一个最简单的 Linux 虚拟机,把 QEMU 的基本操作搞熟。等你理解了启动参数的套路,再切到 ARM64 也不会慌。

2.1 不同平台的安装选择

QEMU 在各主流平台都有现成安装方式,我按平台列一下:

  • Linux(Debian/Ubuntu):sudo apt install qemu-system-x86 qemu-system-arm qemu-utils,Fedora/RHEL 用dnf install qemu-kvm,这里注意 Debian 系把模拟器和工具拆得比较细。

  • macOS:brew install qemu,Homebrew 会一起装好常见固件和工具。

  • Windows:去 qemu.org 下载官方 Windows 安装包,或者直接用包管理器:

    winget install --id QEMU.QEMU -e

    安装完记得把安装目录加入 PATH,或者直接用完整路径调用qemu-system-aarch64.exe。

  • 安卓 Termux:pkg install qemu-system-aarch64 qemu-utils,后面专门有一节讲。

安装完测试一下:

qemu-system-x86_64 --version qemu-img --version

看到版本号就说明基础环境没问题。

2.2 qemu-img:创建磁盘镜像的基本功

QEMU 不像 VirtualBox 那样有图形化向导,磁盘镜像是用命令创建的。我先说最常用的格式区别:

  • raw:就是裸数据,性能好,但不支持快照,多大文件占多大空间;
  • qcow2:QEMU 独有的写时复制格式,创建时只占用实际写入的大小,支持快照、压缩、加密,是日常使用首选。

创建一块 8G 的 qcow2 磁盘:

qemu-img create -f qcow2 disk.img 8G

查看镜像信息:

qemu-img info disk.img

后面如果需要扩容:

qemu-img resize disk.img 12G

注意 resize 只是调大镜像文件,客户机里面的分区表不会自动变,需进系统用分区工具扩展,这块到最后的坑位再展开。

2.3 一个最小可用启动命令

以 x86_64 宿主机跑 Alpine Linux 为例,先把安装 ISO 下载下来,然后执行:

qemu-system-x86_64 \ -m 2048 \ -smp 2 \ -enable-kvm \ -cdrom alpine-virt-3.20.0-x86_64.iso \ -drive file=disk.img,format=qcow2,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ -boot d \ -nographic

这行命令的参数逐个解释一下:

  • -m 2048:内存 2G。
  • -smp 2:两个 vCPU。
  • -enable-kvm:Linux 宿主机且是 x86 客户机时使用硬件加速,速度会快很多。
  • -cdrom:挂载 ISO 光驱。
  • -drive file=disk.img,format=qcow2,if=virtio:挂载磁盘,接口用 virtio,性能比模拟 IDE 好。
  • -netdev user,id=n1,hostfwd=tcp::2222-:22:用户态网络,并把宿主机的 2222 端口转发到客户机的 22 端口。
  • -device virtio-net-pci,netdev=n1:给客户机添加一张 virtio 网卡。
  • -boot d:优先从光驱启动。
  • -nographic:不使用图形窗口,串口输出直接打到当前终端,适合服务器和无桌面环境。

装完系统后重启,去掉-cdrom和-boot d,从磁盘启动:

qemu-system-x86_64 \ -m 2048 -smp 2 -enable-kvm \ -drive file=disk.img,format=qcow2,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ -nographic

主机上用ssh -p 2222 root@127.0.0.1就能连进虚拟机,用户态网络模式下客户机的 IP 固定是 10.0.2.15,端口转发都在宿主机 127.0.0.1 上监听,这个常识后面排查网络时会用到。

3. 真正折腾的开始:用 qemu-system-aarch64 模拟 ARM64

跨架构模拟是你搜索 QEMU 时最常碰到的话题,尤其是“qemu模拟arm64”。这个玩法在调试 ARM 软件、测试 aarch64 发行版时几乎是刚需。我先给你打好心理预期:这玩意儿跑起来是能用的,但不要指望它有物理机性能,一个简单的安装流程可能要等十几分钟甚至更久,属正常现象。

3.1 为什么跨架构模拟会这么慢

前面说了,TCG 要边翻译边执行,每条 ARM 指令都被拆成若干条 x86 微操作再来执行,等效于指令级解释。加上要模拟内存管理、中断、DMA 等,整个系统的开销非常大。

实测感受大概是:在 i5 级别的 x86 CPU 上跑 ARM64 Alpine 的文本安装界面,每一次按键响应都有明显延迟;如果跑带桌面的 openEuler,开机到登录可能要几分钟。这不是你命令写错了,纯粹是物理规律。

想缓解的话,可以:

  • 用-cpu max让 QEMU 启用支持的最大特性集,某些场景比固定cortex-a57更快;
  • 用 virtio 半虚拟化设备,别用模拟的 IDE 网卡;
  • 内存和 CPU 别给太少,2G 内存两个核是最低要求;
  • 不要同时开图形界面和多个后台任务。

3.2 跑通 Alpine ARM64 的完整启动命令

以宿主 Debian/Ubuntu 为例,先装好需要的固件:

sudo apt install qemu-system-arm qemu-efi-aarch64

qemu-efi-aarch64提供 UEFI 固件,ARM64 的 virt 机器没有传统 BIOS,必须用 UEFI 引导,很多新手卡在这一步。

然后下载 ARM64 版 Alpine ISO:

wget https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/aarch64/alpine-virt-3.20.0-aarch64.iso qemu-img create -f qcow2 alpine-arm64.img 8G

启动命令:

qemu-system-aarch64 \ -M virt \ -cpu max \ -m 2048 \ -smp 2 \ -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \ -cdrom alpine-virt-3.20.0-aarch64.iso \ -drive file=alpine-arm64.img,format=qcow2,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ -serial stdio -display none

这里的参数有几点和 x86 不同:

  • -M virt:ARM64 下最通用的虚拟机型,没有具体主板型号,就是一个标准 ARM 虚拟平台。
  • -cpu max:让 TCG 放开手脚启用所有支持的特性,兼容性最好。
  • -bios:指定 UEFI 固件文件。不同发行版路径不一样,Debian 系常见于/usr/share/qemu-efi-aarch64/QEMU_EFI.fd,Fedora 系在/usr/share/edk2/aarch64/QEMU_EFI.fd。
  • -serial stdio -display none:把串口输出到当前终端。如果你用-nographic要注意,ARM64 机器的串口设备名是ttyAMA0,某些发行版引导时需要追加console=ttyAMA0参数才能看到输出。

如果你发现串口没有显示,可以在 UEFI 启动菜单里按e编辑内核命令行,追加console=ttyAMA0。这个细节不同版本略有差异,按你实际镜像调整。

3.3 Alpine 的安装与网络检查

进入 Alpine 安装界面后,用root登录(默认无密码),执行:

setup-alpine

按提示选择键盘、主机名、网络等。网络这里不用慌张,QEMU 的用户态网络会自动提供 DHCP,客户机一般能拿到 10.0.2.15 这个地址。

装到磁盘时执行:

setup-disk

选择把系统写入/dev/vda,也就是我们挂载的 virtio 磁盘。写完后重启。

第二次启动时去掉光盘参数:

qemu-system-aarch64 \ -M virt -cpu max -m 2048 -smp 2 \ -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \ -drive file=alpine-arm64.img,format=qcow2,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ -serial stdio -display none

登录后用:

ip a

确认有eth0和 IP 地址,再测一下外网:

ping -c 3 223.5.5.5

如果能通,说明网络没问题。之后你就能在客户机里apk add装各种软件了。

4. Windows 上装 openEuler ARM 虚拟机:一次完整的跨架构实操记录

“windows使用qemu安装openeuler arm虚拟机”是很多人搜的热词。为什么大家愿意在 Windows 上折腾这个?因为想体验 openEuler 的 ARM64 版本,但手头没有 ARM 服务器。我完整走了一遍,把链路整理出来,这里有个容易误导人的认知:QEMU 在 Windows 上可以模拟任意架构的客户机,但 WHPX 加速只对 x86 客户机有效,ARM64 客户机依然是纯 TCG 模拟,所以在 Windows 上装 openEuler ARM 会明显比本机架构慢,要有心理准备。

4.1 镜像下载与固件准备

openEuler 的 aarch64 ISO 去官方仓库找,比如 22.03 LTS 版本的 aarch64 目录:

https://repo.openeuler.org/openEuler-22.03-LTS/ISO/aarch64/

下载openEuler-22.03-LTS-aarch64-dvd.iso,文件比较大,接近 4GB,注意磁盘空间。

Windows 版 QEMU 安装包在qemu.org,装完后在安装目录的share子目录下一般能找到edk2-aarch64-code.fd,这就是 ARM64 的 UEFI 固件。如果找不到,我建议先在 WSL 或 Linux 机器上装一个qemu-efi-aarch64包,把固件拷过来用。这是比较稳妥的做法,别自己猜路径。

创建磁盘:

qemu-img create -f qcow2 openeuler-arm64.img 32G

openEuler 默认安装会比 Alpine 占空间,32G 起步比较安心。

4.2 启动安装的完整命令

Windows 上用 CMD 或 PowerShell 都行,注意 PowerShell 换行用反引号,CMD 用^。CMD 下命令是:

qemu-system-aarch64.exe ^ -M virt ^ -cpu cortex-a72 ^ -smp 4 ^ -m 4096 ^ -bios edk2-aarch64-code.fd ^ -cdrom openEuler-22.03-LTS-aarch64-dvd.iso ^ -drive file=openeuler-arm64.img,format=qcow2,if=virtio ^ -netdev user,id=n1,hostfwd=tcp::2223-:22 ^ -device virtio-net-pci,netdev=n1 ^ -device virtio-gpu-pci ^ -device virtio-keyboard-pci ^ -device virtio-tablet-pci ^ -vnc 127.0.0.1:1

有两处我必须强调:

第一,ARM64 的 virt 机器默认没有显示设备和输入设备,你不加下面这三行,VNC 里会没有画面、没有键盘鼠标:

-device virtio-gpu-pci -device virtio-keyboard-pci -device virtio-tablet-pci

第二,VNC 监听地址写成127.0.0.1:1是只允许本机连接,端口是 5901。别用:1的写法暴露到局域网,除非你知道自己在做什么。

用 VNC Viewer 连接127.0.0.1:5901,会看到 openEuler 的安装界面。安装过程里选择“服务器”或者带桌面的版本都可以,磁盘选我们挂载的 virtio 盘,软件源默认走光盘镜像,不用联网也能装完。

4.3 装完后的启动参数与使用建议

安装完成后,去掉-cdrom参数,再次启动:

qemu-system-aarch64.exe ^ -M virt ^ -cpu cortex-a72 ^ -smp 4 ^ -m 4096 ^ -bios edk2-aarch64-code.fd ^ -drive file=openeuler-arm64.img,format=qcow2,if=virtio ^ -netdev user,id=n1,hostfwd=tcp::2223-:22 ^ -device virtio-net-pci,netdev=n1 ^ -device virtio-gpu-pci ^ -device virtio-keyboard-pci ^ -device virtio-tablet-pci ^ -vnc 127.0.0.1:1

如果你设置了打开 SSH 服务,宿主机直接:

ssh -p 2223 root@127.0.0.1

整体感受是:安装阶段最煎熬,图形界面卡顿明显,建议耐着性子把必选项配置完就尽快跳到重启;进了系统以后,纯命令行 SSH 会话比 VNC 图形界面流畅得多,日常维护完全够用。

5. 手机上的极限操作:Termux 里装 QEMU 跑 ARM64

在手机上折腾 QEMU 属于“能跑就行”的快乐。我知道这很不实用,但你要是和我一样,出门在外想随时掏出手机看一眼 ARM64 环境,会理解这种执念。Termux 是安卓上的终端模拟器,它提供了完整的 Linux 用户态环境,能直接装 QEMU。

5.1 Termux 环境准备

首先更新源并安装软件包:

pkg update pkg install qemu-system-aarch64 qemu-utils

这个包比较大,大概几百兆,建议在 Wi-Fi 环境下装。装完确认:

qemu-system-aarch64 --version

再给 Termux 开放存储权限,方便把镜像放到共享目录:

termux-setup-storage

镜像文件建议放在~/storage/downloads这样的位置,和电脑互传方便。

5.2 在 Termux 里启动 Alpine ARM64

手机性能有限,我建议跑最小化的 Alpine,不要跑桌面。用 Alpine 的 virt ISO 配合 UEFI 固件启动,命令和电脑上差不多:

qemu-system-aarch64 \ -M virt \ -cpu max \ -m 1024 \ -smp 2 \ -bios /data/data/com.termux/files/usr/share/qemu/edk2-aarch64-code.fd \ -cdrom alpine-virt-3.20.0-aarch64.iso \ -drive file=alpine-arm64.img,format=qcow2,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ -nographic

Termux 的 QEMU 包一般会把固件装在$PREFIX/share/qemu/下,你可以先用find找一下:

find $PREFIX/share/qemu -name "*aarch64*"

如果确实没有固件,退而求其次,下载 Alpine 的 aarch64 netboot 文件(vmlinuz-virt、initramfs-virt),用内核直载方式启动:

qemu-system-aarch64 \ -M virt -cpu max -m 1024 -smp 2 \ -kernel vmlinuz-virt \ -initrd initramfs-virt \ -append "console=ttyAMA0" \ -drive file=alpine-arm64.img,format=qcow2,if=virtio \ -netdev user,id=n1,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=n1 \ -nographic

这个方式的优点是省掉 UEFI 层,启动快一点点;缺点是 modloop(模块镜像)得自己处理,不同 Alpine 小版本的参数有差异。我的建议是:能搞到 UEFI 固件就用标准方式,省心。

5.3 手机模拟的性能和心态建议

实测在骁龙 8 系手机上,1024M 内存跑 Alpine ARM64 的安装,一个setup-alpine交互要等好几秒才刷新一次界面,输错一个字符都让你崩溃。更现实的做法是:

  • 提前把安装命令想好,少打交互式命令;
  • 或者直接在电脑上把系统装好,再把磁盘镜像传到手机上用;
  • 把-m调小到 768M,给手机系统留内存,免得整个机器卡死;
  • 不要开图形界面。

手机跑 QEMU 最大的价值不是性能,而是验证“ARM64 架构的软件在这个环境下的基本行为”。想真正干活,还是老老实实用电脑。

6. 这些坑我替你们踩过了:QEMU 常见问题的排查思路

最后这部分是纯干货,每个问题都是我在不同系统上切实遇到过的,我按“现象 → 原因 → 解法”的方式写,你可以直接对照。

6.1 提示 KVM 不可用或加速失效

现象:在 Linux 上启动虚拟机报:

Could not access KVM kernel module: No such file or directory kvm_init_vcpu failed: Invalid argument

原因:宿主机的/dev/kvm不存在,或者 CPU 不支持嵌套虚拟化。

排查:

ls -l /dev/kvm cat /proc/cpuinfo | grep -c vmx

解法:

  • 物理机上装好 KVM 模块,或者确保用户在kvm组;
  • 云服务器/虚拟机里跑 QEMU 要打开嵌套虚拟化选项;
  • 如果只是跨架构模拟 ARM64,直接去掉-enable-kvm,QEMU 默认会走 TCG。

要特别强调:x86 宿主机上模拟 ARM64,KVM 本来就帮不上忙,别在加速上浪费时间。

6.2 卡在 UEFI 黑屏或者找不到固件

现象:启动qemu-system-aarch64报:

Could not load ROM file: /usr/share/qemu-efi-aarch64/QEMU_EFI.fd

或者启动后屏幕一直黑。

原因:没有安装 ARM64 的 UEFI 固件包,或者-bios路径写错了。

解法:

  • Debian/Ubuntu 装qemu-efi-aarch64;
  • Fedora 装edk2-aarch64;
  • 确认固件路径后用-bios指定绝对路径。

黑屏还有一个可能原因:你用了-display none但客户机的内核输出到了图形设备而不是串口。这时候把参数改成-serial stdio -display none,或者干脆开 VNC,能看到画面再判断。

6.3 客户机网络不通,SSH 连不上

现象:客户机能登录,但ping外网不通;或者宿主机ssh -p 2222 root@127.0.0.1连接被拒。

排查顺序:

  1. 客户机里先看ip a,有没有拿到 10.0.2.x 地址;
  2. 没有地址就执行udhcpc -i eth0或者检查 DHCP 客户端;
  3. 能 ping 通网关但上不了外网,检查宿主机 DNS,/etc/resolv.conf是否正常;
  4. SSH 连不上,先确认客户机里 sshd 启动了:service sshd start;
  5. 确认hostfwd的宿主机端口没被占用:netstat -ano | findstr 2222(Windows)或ss -lntp | grep 2222(Linux)。

另外注意,用户态网络模式下,从宿主机连客户机只能用hostfwd转发的端口,不能直接连接客户机的 IP,因为 10.0.2.0/24 是 QEMU 内部的 NAT 网段。

6.4 磁盘空间不够,怎么给镜像扩容

现象:客户机提示磁盘满。

解法:先在宿主机扩大镜像:

qemu-img resize alpine-arm64.img +8G

然后进客户机,扩展分区和文件系统。以 Alpine 的 ext4 为例:

# 查看分区情况 fdisk -l /dev/vda # 用 parted 或 fdisk 扩展分区,找到一个空闲空间并扩大分区 # 扩展根分区后让内核重读分区表 partprobe /dev/vda # 扩展文件系统 resize2fs /dev/vda2

如果是 btrfs:

btrfs filesystem resize max /

扩容这个操作没什么黑科技,就是分区工具 + 文件系统工具两件事。记住:resize 镜像文件只是把容器变大了,客户机里的分区表不会自动变。

6.5 进来慢、卡顿严重,有没有优化手段

除了换硬件,QEMU 侧能做的优化如下:

  • 磁盘和网卡都用 virtio 设备,不要用if=ide或模拟 e1000;
  • 尽量用-cpu max而不是老旧的cortex-a57;
  • 给足内存,跨架构模拟场景 2G 内存和 1G 内存差距很大;
  • 不需要图形的时候用-nographic或-display none,图形渲染开销省掉一大截;
  • 如果是 x86 客户机在 x86 宿主机上,务必开 KVM,性能差距是数量级的。

我自己的习惯是:把所有常用的启动参数写成一个启动脚本放在项目目录里,避免每次敲一长串命令。比如 Linux 下写个run.sh,Windows 下写个run.bat,参数变更只改脚本即可。

最后的建议

QEMU 这东西,入门门槛主要不在命令,而在对“模拟 vs 虚拟化”的理解。你只要记住:同架构用 KVM 加速,跨架构认命用 TCG,设备尽量选 virtio,网络优先用 user 模式加端口转发,就足够应付绝大多数场景。我个人实际操作中,最常被问到的问题其实是“为什么这么慢”,每次回答完都会补一句:跨架构模拟能跑通已经是胜利,慢才是常态。希望这篇能帮你少走点弯路,少熬几个夜。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询