强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

QEMU 虚拟化完全指南 / 12 - ARM/RISC-V 仿真

12 - ARM/RISC-V 仿真

掌握使用 QEMU 进行 ARM64 和 RISC-V 架构的全系统仿真、交叉编译与嵌入式开发。


12.1 多架构仿真概述

QEMU 最强大的特性之一是跨架构仿真(Cross-architecture Emulation),可以在 x86_64 主机上运行 ARM、RISC-V、MIPS、PowerPC 等架构的操作系统和应用程序。

QEMU 多架构仿真支持:
  主机 (x86_64 Linux)
    ├── qemu-system-aarch64    → ARM64 全系统仿真
    ├── qemu-system-arm        → ARM32 全系统仿真
    ├── qemu-system-riscv64    → RISC-V 64 位仿真
    ├── qemu-system-riscv32    → RISC-V 32 位仿真
    ├── qemu-system-mips       → MIPS 大端序仿真
    ├── qemu-system-mipsel     → MIPS 小端序仿真
    ├── qemu-system-ppc64      → PowerPC 64 位仿真
    ├── qemu-system-s390x      → IBM System z 仿真
    └── qemu-system-sparc64    → SPARC 64 位仿真

支持的架构一览

架构系统仿真用户仿真常见用途
aarch64 (ARM64)移动/嵌入式/服务器开发
arm (ARM32)IoT/嵌入式
riscv64RISC-V 开发
riscv32RISC-V 嵌入式
mips/mipsel路由器/嵌入式
ppc64/ppcIBM POWER 服务器
s390xIBM 大型机
sparc64传统 UNIX

12.2 ARM64 (AArch64) 全系统仿真

安装 ARM64 仿真环境

# 安装 QEMU ARM64 系统仿真器
sudo apt install -y qemu-system-arm qemu-efi-aarch64

# 下载 ARM64 系统镜像(Debian 示例)
wget https://cdimage.debian.org/cdimage/cloud/sid/daily/latest/debian-sid-nocloud-arm64-daily.qcow2

# 或者使用 Ubuntu cloud 镜像
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-arm64.img

使用 UEFI 启动 ARM64 虚拟机

# 准备 UEFI 固件变量文件
cp /usr/share/AAVMF/AAVMF_VARS.fd my-arm64-vars.fd

# 创建磁盘
qemu-img create -f qcow2 arm64-disk.qcow2 20G

# 下载 ARM64 安装 ISO
wget https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-12.x-arm64-netinst.iso

# 启动安装
qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a72 \
  -m 4G \
  -smp 4 \
  -bios /usr/share/AAVMF/AAVMF_CODE.fd \
  -drive if=pflash,format=raw,file=my-arm64-vars.fd \
  -drive file=arm64-disk.qcow2,format=qcow2,if=virtio \
  -cdrom debian-12.x-arm64-netinst.iso \
  -boot order=d \
  -device virtio-gpu-pci \
  -device usb-ehci \
  -device usb-kbd \
  -device usb-mouse \
  -device virtio-net-pci,netdev=net0 \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -display sdl

ARM64 启动后配置

安装完成后,去掉 -cdrom 参数从硬盘启动:

qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a72 \
  -m 4G \
  -smp 4 \
  -bios /usr/share/AAVMF/AAVMF_CODE.fd \
  -drive if=pflash,format=raw,file=my-arm64-vars.fd \
  -drive file=arm64-disk.qcow2,format=qcow2,if=virtio \
  -device virtio-net-pci,netdev=net0 \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -nographic \
  -append "console=ttyAMA0"

ARM64 机器类型

机器类型说明
virt通用虚拟机(推荐,最灵活)
virt-2.12virt 2.12 版本
virt,gic-version=3指定 GIC 版本
raspi3bRaspberry Pi 3 Model B
raspi4bRaspberry Pi 4 Model B
xlnx-zcu102Xilinx ZCU102 开发板
sbsa-refSBSA 参考平台

ARM64 CPU 类型

# 查看支持的 CPU 类型
qemu-system-aarch64 -cpu help

# 常用 CPU:
# cortex-a53    - ARMv8, 低功耗
# cortex-a57    - ARMv8, 高性能
# cortex-a72    - ARMv8, Raspberry Pi 4
# cortex-a76    - ARMv8.2, 高性能
# max           - 支持所有特性(最快)

12.3 RISC-V 全系统仿真

安装 RISC-V 仿真环境

# 安装 QEMU RISC-V 系统仿真器
sudo apt install -y qemu-system-misc

# 验证
qemu-system-riscv64 --version
qemu-system-riscv32 --version

RISC-V 64 位虚拟机

# 下载 RISC-V 预编译镜像
# 使用 openEuler 或 Fedora RISC-V 镜像
wget https://mirror.tuna.tsinghua.edu.cn/openeuler/openEuler-22.03-LTS/riscv64/images/openEuler-22.03-V1-base-qemu-riscv64.qcow2

# 下载 OpenSBI + U-Boot 固件
wget https://mirror.tuna.tsinghua.edu.cn/openeuler/openEuler-22.03-LTS/riscv64/images/fw_payload-uboot-qemu-riscv64.bin

# 启动 RISC-V 虚拟机
qemu-system-riscv64 \
  -M virt \
  -cpu rv64 \
  -m 4G \
  -smp 4 \
  -bios fw_payload-uboot-qemu-riscv64.bin \
  -drive file=openEuler-22.03-V1-base-qemu-riscv64.qcow2,format=qcow2,if=virtio \
  -device virtio-net-pci,netdev=net0 \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -nographic

RISC-V 无固件直接启动

# 使用内核直接启动(无需 U-Boot)
qemu-system-riscv64 \
  -M virt \
  -cpu rv64 \
  -m 2G \
  -smp 2 \
  -kernel /path/to/Image \
  -initrd /path/to/initrd.img \
  -append "root=/dev/vda rw console=ttyS0" \
  -drive file=riscv64-rootfs.qcow2,format=qcow2,if=virtio \
  -nographic

RISC-V CPU 类型

CPU 类型说明
rv64基础 RV64GC
rv32基础 RV32GC
rv64,v=true启用向量扩展 (V)
rv64,zba=true,zbb=true位操作扩展

12.4 交叉编译环境

安装交叉编译工具链

# ARM64 交叉编译
sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
sudo apt install -y binutils-aarch64-linux-gnu

# RISC-V 交叉编译
sudo apt install -y gcc-riscv64-linux-gnu g++-riscv64-linux-gnu
sudo apt install -y binutils-riscv64-linux-gnu

# ARM32 交叉编译
sudo apt install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

交叉编译示例

# 编写测试程序
cat > hello.c << 'EOF'
#include <stdio.h>
int main() {
    printf("Hello from cross-compiled binary!\n");
    printf("Architecture: ");
#if defined(__aarch64__)
    printf("ARM64\n");
#elif defined(__riscv) && __riscv_xlen == 64
    printf("RISC-V 64\n");
#elif defined(__arm__)
    printf("ARM32\n");
#else
    printf("Unknown\n");
#endif
    return 0;
}
EOF

# 交叉编译 ARM64
aarch64-linux-gnu-gcc -o hello-arm64 hello.c -static

# 交叉编译 RISC-V
riscv64-linux-gnu-gcc -o hello-riscv64 hello.c -static

# 验证二进制文件架构
file hello-arm64
file hello-riscv64

# 使用 qemu-user 直接运行
qemu-aarch64 ./hello-arm64
qemu-riscv64 ./hello-riscv64

12.5 嵌入式开发

使用 QEMU 模拟嵌入式 Linux

# ARM Versatile 开发板
qemu-system-arm \
  -M versatilepb \
  -cpu arm1176 \
  -m 256M \
  -kernel zImage \
  -dtb versatile-pb.dtb \
  -drive file=rootfs.ext4,if=scsi,format=raw \
  -append "root=/dev/sda rw console=ttyAMA0" \
  -nographic

# RISC-V SiFive Unleashed
qemu-system-riscv64 \
  -M sifive_u \
  -m 8G \
  -kernel Image \
  -drive file=rootfs.img,format=raw,if=virtio \
  -append "root=/dev/vda rw console=ttySIF0" \
  -nographic

裸机程序调试

# 编写 ARM64 裸机程序
cat > boot.S << 'EOF'
.section .text
.global _start
_start:
    ldr x0, =0x09000000  // UART 地址 (QEMU virt)
    adr x1, msg
    ldr w2, =len
1:  ldrb w3, [x1], #1
    strb w3, [x0]
    subs w2, w2, #1
    b.ne 1b
2:  wfi
    b 2b

msg: .ascii "Hello from bare metal ARM64!\n"
len = . - msg
EOF

# 编译
aarch64-linux-gnu-gcc -nostdlib -nostartfiles -ffreestanding \
  -o boot.elf boot.S -Ttext=0x40000000

# 运行
qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a53 \
  -m 128M \
  -kernel boot.elf \
  -nographic \
  -semihosting

GDB 调试嵌入式程序

# 启动 QEMU 并等待 GDB 连接
qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a53 \
  -m 256M \
  -kernel firmware.elf \
  -nographic \
  -S -gdb tcp::1234

# 在另一个终端启动 GDB
aarch64-linux-gnu-gdb firmware.elf
# (gdb) target remote :1234
# (gdb) break main
# (gdb) continue

12.6 使用 QEMU 运行容器镜像

在 ARM64 环境中运行 Docker

# 在 ARM64 虚拟机中安装 Docker
ssh -p 2222 root@localhost
apt install docker.io

# 在虚拟机内运行 ARM64 容器
docker run --rm -it arm64v8/ubuntu:22.04 uname -a
# 输出: Linux ... aarch64 GNU/Linux

构建多架构镜像

# 在 x86_64 主机上使用 QEMU 构建 ARM64 镜像
docker buildx build --platform linux/arm64 -t myapp:arm64 .

详细的多架构构建请参见 第 15 章 - Docker 中的 QEMU


12.7 常见问题与性能优化

性能对比

模式相对性能适用场景
TCG (纯仿真)5-20%开发、测试、调试
KVM (同架构)95-99%仅限相同架构
用户模式10-30%程序测试

加速仿真性能

# 使用多线程 TCG(QEMU 6.0+)
qemu-system-aarch64 -accel tcg,thread=multi ...

# 增加 TCG 翻译缓存
qemu-system-aarch64 -accel tcg,tb-size=256 ...

# 使用 `-cpu max` 启用所有特性(减少模拟开销)
qemu-system-aarch64 -cpu max ...

常见问题

问题原因解决方案
启动极慢TCG 纯仿真使用 cloud 镜像减小启动开销
网络不通默认网络配置检查 virtio-net 配置
UEFI 启动失败固件路径错误检查 AAVMF/OVMF 路径
内核 panic内核不匹配使用对应架构的内核

要点回顾

要点核心内容
ARM64 仿真qemu-system-aarch64 + virt 机器类型
RISC-V 仿真qemu-system-riscv64 + OpenSBI/U-Boot
交叉编译gcc-aarch64-linux-gnu / gcc-riscv64-linux-gnu
用户模式qemu-aarch64 直接运行交叉编译的二进制
性能TCG 约 5-20%,仅用于开发测试

注意事项

性能限制: 跨架构 TCG 仿真性能仅为原生的 5-20%,不适合运行性能敏感型工作负载。如需在 ARM64 上运行高性能应用,建议使用物理 ARM64 服务器或云实例。

UEFI 固件: ARM64 虚拟机需要 UEFI 固件(AAVMF)。不同发行版的固件路径可能不同。

RISC-V 生态: RISC-V 生态仍在快速发展,某些软件可能尚未移植到 RISC-V。


扩展阅读


下一步

13 - 用户模式:学习 qemu-user 静态翻译与 binfmt_misc 跨架构运行。