嵌入式项目QEMU仿真与Linux内核调试实践 - 第3节
3.1 QEMU 命令行参数详解
QEMU 是一个功能强大的开源机器模拟器,其命令行参数体系决定了虚拟机的硬件配置、启动方式与调试能力。掌握核心参数是进行嵌入式仿真与内核调试的第一步。以下按功能分类列出最常用的参数组。
3.1.1 机器与 CPU 配置
| 参数 | 说明 | 典型值示例 |
|---|---|---|
-machine |
指定模拟的硬件平台 | virt, vexpress-a9, raspi3b |
-cpu |
选择 CPU 型号 | cortex-a53, max, host |
-smp |
设置 CPU 核心数 | 4, 2 |
-m |
分配内存大小 | 512M, 1G, 2G |
提示: 嵌入式开发中
-machine virt 是最通用的选择,它提供标准设备树与 UART,适合快速验证内核启动流程。
3.1.2 存储与启动设备
| 参数 | 说明 | 典型值示例 |
|---|---|---|
-kernel |
指定内核镜像文件 | arch/arm64/boot/Image |
-initrd |
指定初始 RAM 磁盘 | rootfs.cpio.gz |
-drive |
添加磁盘驱动器 | file=disk.img,format=raw,if=virtio |
-cdrom |
挂载光盘镜像 | debian.iso |
-boot |
设置启动顺序 | order=c (硬盘优先) |
3.1.3 网络配置
| 参数 | 说明 | 典型值示例 |
|---|---|---|
-netdev |
定义后端网络设备 | user,id=net0 |
-device |
添加前端网卡设备 | virtio-net,netdev=net0 |
-nic |
简写方式配置网络 | user,model=virtio |
3.1.4 显示与串口
| 参数 | 说明 | 典型值示例 |
|---|---|---|
-nographic |
无图形界面,使用终端 | (无参数值) |
-serial |
重定向串口 | mon:stdio, file:serial.log |
-vga |
选择显卡类型 | virtio, cirrus |
-display |
显示后端 | gtk, sdl, none |
调试专用参数:
-s 等价于 -gdb tcp::1234,在 1234 端口等待 GDB 连接。-S 在启动时暂停 CPU,等待调试器继续执行。
3.2 启动一个虚拟机
以下演示如何从零启动一个基于 ARM64 架构的 QEMU 虚拟机,使用 virt 平台与 Linux 内核。
3.2.1 准备启动文件
需要准备以下文件:
- 内核镜像:
Image(ARM64 非压缩内核) - 设备树文件:
virt.dtb(QEMU 自动生成,也可手动指定) - 根文件系统:
rootfs.cpio.gz(initramfs)
3.2.2 最小启动命令
qemu-system-aarch64 \
-machine virt \
-cpu cortex-a53 \
-smp 2 \
-m 512M \
-kernel Image \
-initrd rootfs.cpio.gz \
-nographic \
-append "console=ttyAMA0 root=/dev/ram rdinit=/sbin/init"
关键点:
console=ttyAMA0 将内核输出重定向到 QEMU 模拟的 PL011 UART,配合 -nographic 可在当前终端看到启动日志。
3.2.3 带磁盘的完整启动
qemu-system-aarch64 \
-machine virt \
-cpu cortex-a53 \
-smp 2 \
-m 1G \
-kernel Image \
-drive file=rootfs.ext4,format=raw,if=virtio \
-append "root=/dev/vda console=ttyAMA0" \
-netdev user,id=net0 \
-device virtio-net,netdev=net0 \
-nographic
3.3 QEMU Monitor 使用
QEMU Monitor 是运行中的虚拟机控制接口,允许在宿主机上执行设备热插拔、快照、调试等操作。进入 Monitor 的方式取决于启动参数。
3.3.1 进入 Monitor
| 启动方式 | 进入 Monitor 快捷键 | 说明 |
|---|---|---|
| 图形界面 (GTK/SDL) | Ctrl + Alt + 2 |
切换到 Monitor 窗口 |
| 无图形界面 (-nographic) | Ctrl + A, 然后按 C |
在串口终端中切换 |
| 串口重定向 (-serial mon:stdio) | Ctrl + A, 然后按 C |
Monitor 与串口复用 stdio |
3.3.2 常用 Monitor 命令
| 命令 | 功能 | 示例 |
|---|---|---|
help |
列出所有可用命令 | help |
info |
查询系统状态 | info cpus, info block |
system_reset |
复位虚拟机 | system_reset |
system_powerdown |
关闭虚拟机 | system_powerdown |
stop |
暂停所有 CPU | stop |
cont |
继续执行 | cont |
quit |
退出 QEMU | quit |
device_add |
热添加设备 | device_add virtio-blk,drive=disk2 |
device_del |
移除设备 | device_del virtio-blk |
savevm |
保存快照 | savevm snapshot1 |
loadvm |
加载快照 | loadvm snapshot1 |
3.3.3 调试场景:使用 Monitor 检查内核状态
当内核卡死或需要查看寄存器时,Monitor 提供以下调试命令:
# 进入 Monitor 后执行
(qemu) stop # 暂停虚拟机
(qemu) info registers # 查看所有 CPU 寄存器
(qemu) info cpus # 查看 CPU 状态
(qemu) info mtree # 查看内存树布局
(qemu) info qtree # 查看 QOM 设备树
(qemu) cont # 恢复执行
注意:
info registers 在 -nographic 模式下输出到当前终端,可用于分析内核异常时的 PC 指针位置与堆栈状态。
3.3.4 实用技巧:将 Monitor 输出重定向到文件
在调试长时间运行的内核时,可以将 Monitor 输出保存到日志文件:
# 启动时添加 -D 参数
qemu-system-aarch64 [...] -D monitor.log
# 进入 Monitor 后执行
(qemu) log all
(qemu) info registers
(qemu) log none
上述操作会将 Monitor 的完整输出写入 monitor.log,便于事后分析。
本章核心要点:
-machine与-cpu决定仿真平台,virt是嵌入式调试首选。- 最小启动命令包含
-kernel、-initrd、-nographic与-append。 - Monitor 通过
Ctrl+A, C进入,提供stop/cont/info等调试命令。 -s与-S是 GDB 联合调试的入口参数,将在后续章节深入讲解。