前几节从源码层级分析了QEMU/KVM CPU虚拟化的完整流程,不难发现大部分工作都由KVM完成,QEMU主要负责维护虚拟机和vCPU模型,并通过KVM模块文件描述符、虚拟机文件描述符和vCPU文件描述符调用KVM API接口,本书参考网上的一个示例 实现了一个类似于QEMU的小程序,执行指定二进制代码输出“Hello,World!”。主要代码如下。
sample-qemu.c
上述例子通过前面所述的若干ioctl调用创建并运行vCPU,将vCPU起始指令地址设置为0x1000(GPA),并将指定的二进制代码复制到相应的内存位置(HVA)。二进制代码将依次调用OUT指令向0x3f8端口写入“Hello,World!”包含的各个字符,触发EXIT_REASON_IO_INSTRUCTION类型的VM-Exit,这使得程序退回到用户态进行处理,用户态程序调用putchar函数输出对应字符。二进制代码最终执行hlt指令触发VM-Exit,系统回到用户态并退出应用程序。