QEMU AArch64 实战:从 User Mode 到 System Mode

发布时间:2026/9/26 11:20:37
QEMU AArch64 实战:从 User Mode 到 System Mode
建议提前阅读虚拟化入门笔记KVM QEMU 虚拟化1. 测试环境本文使用的宿主机信息如下$ cat /proc/version Linux version 6.8.0-87-generic (builddlcy02-amd64-060) (x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04.2) 12.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #88~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Oct 14 14:03:14 UTC 2需要特别注意宿主机是 x86_64而客户机是 AArch64两者指令集不同因此 System Mode 只能使用 QEMU 的 TCG 动态二进制翻译不能使用 KVM 硬件虚拟化。如果宿主机本身也是 ARM64并且/dev/kvm可用才可以使用-accelkvm-cpuhost2. User Mode 与 System Mode 的区别对比项User ModeSystem Mode可执行文件qemu-aarch64qemu-system-aarch64模拟范围单个用户态程序完整计算机系统Linux 内核使用宿主机内核启动客户机自己的内核硬件设备不模拟完整硬件模拟 CPU、内存、串口、磁盘、网卡等典型用途交叉编译验证、CI、运行异构程序操作系统启动、驱动开发、内核调试启动速度较快较慢跨架构时尤其明显User Mode 会翻译 ARM64 指令和 Linux 系统调用。例如 ARM64 程序调用write()时QEMU 会将其参数转换后交给宿主机 Linux 内核处理。它不包含客户机内核也不会模拟磁盘控制器或网卡。System Mode 则需要先构造一台虚拟机器。本文使用 QEMU 官方推荐的virt板级模型它不是某块真实开发板而是一个面向虚拟化设计的通用 ARM 平台支持 PCI、VirtIO、PL011 串口和较新的 ARM CPU 模型。3. 编译 QEMU3.1 获取源码QEMU 源码下载参考深入 QEMU Guest Agent虚拟机内外通信的隐形纽带3.2 配置目标并编译mkdir-pbuildcdbuild../configure\--target-listaarch64-linux-user,aarch64-softmmu配置过程中可能会报错根据报错打印apt install 依次安装需要的库即可。这里不再详细介绍每个库的安装过程aarch64-linux-user生成 AArch64 Linux 用户模式模拟器。aarch64-softmmu生成 AArch64 系统模拟器。softmmu是 QEMU 构建系统中 System Mode 目标的名称。配置完成后执行 make 编译命令。make编译完成后build目录中应当至少包含qemu-aarch64 qemu-system-aarch64检查版本和关键功能$:~/Desktop/qemu/build$ ./qemu-system-aarch64--versionQEMU emulator version10.1.0(v10.1.0)Copyright(c)2003-2025 Fabrice Bellard and the QEMU Project developers $:~/Desktop/qemu/build$ ./qemu-aarch64--versionqemu-aarch64 version10.1.0(v10.1.0)Copyright(c)2003-2025 Fabrice Bellard and the QEMU Project developers4. 验证 User Mode4.1 安装 ARM64 交叉编译器下载 aarch64 编译器AArch64 GNU/Linux target (aarch64-none-linux-gnu)# 1. 创建一个目录来存放工具链如果还没有的话mkdir-p~/toolchains# 2. 将下载的文件解压到该目录# 请根据你实际下载的文件名调整下面的命令tar-xvfarm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz-C~/toolchains# 3. 将编译器路径添加到环境变量exportPATH~/toolchains/arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-linux-gnu/bin:$PATH# 4. 验证是否成功aarch64-none-linux-gnu-gcc--version4.2 编译测试程序编译测试程序 hello.c#includestdio.hintmain(){printf(hello world!\n);return0;}aarch64-none-linux-gnu-gcc-static-ohello hello.c这里使用静态链接是为了把程序所需的 C 运行库一起放进 ELF 文件避免运行时寻找 ARM64 动态链接器和共享库。$:~/Desktop/qemu/build$ ./qemu-aarch64 hello hello world!5. 验证 System ModeUser Mode 只证明 QEMU 能运行 ARM64 用户态指令。要验证 System Mode还必须启动一个完整的 ARM64 操作系统。本文选择 Alpine Linux 的Virtual镜像原因是镜像小、默认支持串口控制台和 VirtIO适合作为 QEMU 启动测试。这里不需要安装到虚拟硬盘直接以 Live 模式从 ISO 启动即可。5.1 安装 ARM64 UEFI 固件sudoaptinstallqemu-efi-aarch64Ubuntu 22.04 安装该软件包后会提供/usr/share/qemu-efi-aarch64/QEMU_EFI.fd它是面向 AArch64 虚拟机的 EDK2 UEFI 固件。本文通过-bios加载固件适合一次性启动验证如果需要长期保存 UEFI 变量应改用独立的只读 CODE 和可写 VARS pflash 镜像。5.2 下载 Alpine ARM64 镜像wgethttps://dl-cdn.alpinelinux.org/alpine/v3.24/releases/aarch64/alpine-virt-3.24.2-aarch64.iso这是 Alpine 官方的 ARM64 虚拟机镜像。Alpine 下载页面下载 Virtual → aarch64 版本即可5.3 最小启动命令进入 QEMU 的build目录并根据实际位置修改 ISO 路径./qemu-system-aarch64\-machinevirt\-cpucortex-a57\-acceltcg\-smp2\-m1024\-bios/usr/share/qemu-efi-aarch64/QEMU_EFI.fd\-devicevirtio-scsi-pci,idscsi0\-drivefile../../alpine-virt-3.24.2-aarch64.iso,ifnone,mediacdrom,readonlyon,idcd0\-devicescsi-cd,drivecd0,busscsi0.0\-nographic这条命令没有配置虚拟硬盘所有内容都从 ISO 加载关闭虚拟机后不会保存系统修改。关键参数说明参数作用-machine virt使用 QEMU 通用 ARM 虚拟平台-cpu cortex-a57模拟一颗 64 位 ARMv8 CPU-accel tcg使用 QEMU TCG 进行跨架构指令翻译-smp 2提供 2 个虚拟 CPU-m 1024提供 1 GiB 客户机内存-bios QEMU_EFI.fd加载 AArch64 UEFI 固件virtio-scsi-pci创建 VirtIO SCSI 控制器scsi-cd将 Alpine ISO 作为虚拟光驱连接-nographic禁用图形窗口将串口和 QEMU monitor 接到当前终端启动过程中的关键链路是QEMU 创建virt虚拟硬件并复位 Cortex-A57 CPU。EDK2 固件枚举 PCI 和 VirtIO SCSI 设备。UEFI 从 ISO 的 EFI System Partition 加载引导程序。引导程序加载 ARM64 Linux 内核和 initramfs。内核根据 QEMU 提供的硬件信息初始化 PL011 串口、GIC 和 VirtIO 设备。Alpine 用户空间启动并在串口上显示登录提示。5.4 登录并确认客户机架构启动成功后会看到localhost login:输入用户名rootLive 环境默认没有密码。进入后验证执行以下命令可以正常关机poweroff如果客户机没有响应可以按CtrlA松开后再按X退出-nographic模式下的 QEMU。