2. 使用QEMU监视器控制虚拟机

任务说明

本案例目标是通过QEMU监视器(QEMU Monitor)对运行中的虚拟机执行基本控制操作,包括查看虚拟机运行状态、发送键盘按键事件等。你将启动一个最小化的QEMU虚拟机实例,并通过标准输入/输出或Unix Socket方式接入监视器,验证命令执行效果。

实现方案

QEMU监视器提供了一套交互式命令接口,支持info、sendkey、quit等操作。本案例使用-monitor stdio将监视器绑定到当前终端,同时使用-display none和-serial none避免图形窗口与串口干扰,使监视器成为唯一交互通道。虚拟机使用QEMU自带的isa-debug-exit设备,该设备在收到特定I/O写入后会使QEMU以指定退出码退出,便于验证sendkey等命令是否真正送达虚拟机内部。

代码实现

创建以下启动脚本start_vm.sh:

#!/bin/bash
# 启动一个带监视器的最小QEMU虚拟机
# 使用isa-debug-exit设备:向I/O端口0x501写入值N,QEMU以退出码(N<<1)|1退出

exec qemu-system-x86_64 \
    -M pc \
    -m 64M \
    -display none \
    -serial none \
    -monitor stdio \
    -device isa-debug-exit \
    -nodefaults

赋予执行权限并启动:

chmod +x start_vm.sh
./start_vm.sh

启动后终端进入QEMU监视器交互界面,提示符为(qemu)。

监视器命令操作

在(qemu)提示符后依次输入以下命令并观察输出:

(qemu) info status
# 预期输出: VM status: running

(qemu) info registers
# 预期输出: 显示CPU寄存器快照,RAX=0x0000000000000000 等

(qemu) sendkey ctrl-alt-f1
# 预期输出: (无输出,按键已注入虚拟机)

(qemu) info mice
# 预期输出: 显示当前鼠标设备列表

(qemu) quit
# 预期输出: QEMU进程正常退出,返回终端shell

验证sendkey命令确实生效

仅执行sendkey而无外部观察手段时,无法确认按键是否真正注入。为验证sendkey的实效性,利用isa-debug-exit设备特性:该设备监听I/O端口0x501,当收到写入值N时,QEMU以退出码(N<<1)|1终止。由于虚拟机内无操作系统处理按键,需借助QEMU的sendkey配合isa-debug-exit的I/O端口触发机制——但该设备默认不响应键盘。因此,更直接的验证方式是使用监视器的sendkey向虚拟机发送ctrl-alt-delete,并观察QEMU日志或使用-d选项跟踪中断注入:

# 重新启动,开启中断日志
qemu-system-x86_64 -M pc -m 64M -display none -serial none \
    -monitor stdio -device isa-debug-exit -nodefaults \
    -d int -D /tmp/qemu_int.log

# 在监视器中执行:
(qemu) sendkey ctrl-alt-delete
(qemu) quit

# 检查日志中是否出现键盘控制器中断注入记录
grep -i "kbd\|keyboard\|8042" /tmp/qemu_int.log

若日志中包含键盘控制器(8042)相关中断注入条目,则证明sendkey命令已成功将按键事件送入虚拟机硬件层。

验证方法与判定标准

验证项操作通过标准
监视器可用启动后输入info status输出VM status: running
状态查看输入info registers显示寄存器列表且无错误提示
按键注入输入sendkey ctrl-alt-f1命令无报错,QEMU不退出
按键实际送达开启-d int日志后执行sendkey ctrl-alt-delete日志中出现键盘控制器中断记录
退出监视器输入quitQEMU进程正常结束,shell提示符返回

监视器命令交互流程

QEMU监视器命令交互时序 用户终端 QEMU监视器 虚拟机硬件 启动QEMU (-monitor stdio) (qemu) 提示符 info status VM status: running sendkey ctrl-alt-f1 键盘控制器中断注入 quit 绿色箭头=用户命令 青色箭头=监视器响应 橙色箭头=硬件中断注入

关键说明

  • -nodefaults参数移除了默认设备,确保虚拟机环境最小化,避免默认VGA、键盘等设备干扰监视器行为。
  • isa-debug-exit设备在本案例中作为虚拟机内可观测的退出机制,但验证sendkey时需依赖-d int日志,因为该设备不直接响应键盘输入。
  • 若需在无图形环境下验证按键对客户机操作系统的实际影响,可加载一个极小的内核(如-kernel参数指定编译好的测试内核),但本案例聚焦监视器命令本身,故采用日志验证方式。