qemu 中文文档 下载 App

x86 主机模拟 ARM64:从零搭建完整开发环境

ARM 模拟能做什么

在 x86 主机上模拟 ARM 架构,是 QEMU 最独特的能力之一。没有任何其他虚拟化软件能做到这一点。典型用途:

ARM 模拟的难点

ARM 模拟和 x86 模拟有两个关键差异:

  1. 加速器受限:x86 主机上模拟 ARM 时 TCG 是唯一选择(架构不同,硬件加速不适用)。性能较慢
  2. 板卡选型:ARM 没有统一的"PC"——每种板卡设备组合完全不同。QEMU 提供了几种通用板卡

QEMU 支持的 ARM 板卡

板卡名说明用途
virtQEMU 虚拟 ARM 服务器板跑通用 Linux 发行版,推荐
raspi2bRaspberry Pi 2 Model B模拟树莓派
raspi3apRaspberry Pi 3 Model A+模拟树莓派
versatilepbARM Versatile经典 ARM 开发板
vexpress-a15Vexpress Cortex-A15嵌入式开发
aarch64通用 AArch64最通用

大多数场景用 -M virt 就够了——这是 QEMU 设计的"理想"ARM 服务器板,设备支持最完整。

模拟 ARM64 Linux(virt 板)

准备材料

  1. 内核镜像(vmlinuz)和 initramfs(initrd.img)——从 Ubuntu ARM64 ISO 里提取
  2. 根文件系统(rootfs)——qcow2 格式
  3. 可选:ARM64 ISO 用于全新安装

步骤一:创建根文件系统

qemu-img create -f qcow2 rootfs.qcow2 10G

步骤二:提取内核和 initrd

挂载 Ubuntu ARM64 ISO,从中提取:

步骤三:启动

qemu-system-aarch64 \
  -M virt \
  -m 4G \
  -cpu max \
  -kernel vmlinuz-arm64 \
  -initrd initrd-arm64 \
  -drive file=rootfs.qcow2,format=qcow2,if=virtio \
  -append "root=/dev/vda1 console=ttyAMA0" \
  -netdev user,id=n0,hostfwd=tcp::2222-:22 \
  -device virtio-net-pci,netdev=n0 \
  -nographic

逐行解释:

首次启动安装系统

如果 rootfs.qcow2 是空的,需要先引导 Ubuntu 安装器:

qemu-system-aarch64 \
  -M virt -m 4G -cpu max \
  -cdrom ubuntu-24.04-live-server-arm64.iso \
  -drive file=rootfs.qcow2,format=qcow2,if=virtio \
  -nic user,hostfwd=tcp::2222-:22 \
  -nographic

安装完成后重启,用第一种命令引导新系统。

在 Apple Silicon Mac 上模拟 ARM

Apple Silicon 本身是 ARM64,QEMU 可以用 HVF 加速!

qemu-system-aarch64 \
  -accel hvf \
  -M virt -m 8G -cpu host \
  -kernel vmlinuz \
  -initrd initrd \
  -drive file=rootfs.qcow2,format=qcow2 \
  -append "root=/dev/vda1 console=ttyAMA0" \
  -nographic

这是性能最高的 ARM 模拟方案——Apple Silicon 原生执行 ARM64 指令,性能接近物理机。

注意:-cpu host 在 Apple Silicon 上可能不可用。如果报特性不支持,换成 -cpu max,pauth-impdef=on。

用户态 ARM 模拟

不需要完整系统,只是跑 ARM 编译的二进制:

# 安装用户态模拟器
sudo apt install qemu-user qemu-user-static

# 模拟运行
qemu-aarch64 ./my-arm64-binary

# 带根文件系统
qemu-aarch64-L /opt/arm64-rootfs ./my-arm64-binary

用户态模拟只翻译指令,共享宿主机的系统调用。速度比全系统模拟快得多。

GDB 调试 ARM 内核

QEMU 可以在启动时打开 GDB server,让你在 GDB 里单步调试 Guest 内核:

# QEMU 侧打开 GDB server
qemu-system-aarch64 \
  -M virt -m 4G -smp 4 \
  -kernel vmlinuz -initrd initrd \
  -drive file=rootfs.qcow2,format=qcow2 \
  -append "root=/dev/vda1 nokaslr" \
  -s -S \
  -nographic

# -s 在 1234 端口开 GDB server,-S 启动后暂停等待连接

另一个终端连上去:

# ARM GDB
aarch64-linux-gnu-gdb vmlinux

(gdb) target remote :1234
(gdb) b start_kernel
(gdb) continue

常见问题

Guest 里没有 eth0

virt 板卡的网卡在 Guest Linux 里叫 ens3(或 enp0s1),不是 eth0。Ubuntu 用 netplan,修改 /etc/netplan/*.yaml 配置。

u-boot 引导问题

用 -kernel 跳过 u-boot 是最简单的方式。如果必须用 u-boot(比如要测试 u-boot 本身),需要额外编译 u-boot.bin 并指定。

模拟速度慢

x86 主机上只能用 TCG,速度是 ARM 物理机的 5%~15%。建议:

下一步

ARM 模拟通了?去 RISC-V 模拟 看看同样的套路怎么跑 RISC-V。