上QQ阅读APP看书,第一时间看更新
1.5 一个简单KVM用户空间实例
在本章的最后,我们通过一个具体的KVM用户空间的实例来结束CPU虚拟化的讨论。我们将所有的代码都放在一个文件kvm.c中,定义了一个结构体vm来代表一台虚拟机,为了简单,这台虚拟机只具备计算机的最基本单元,即运算器和内存,因此结构体vm中的主体就是处理器和内存。一台虚拟机可能有多个处理器,每个处理器又有自己的状态(各种寄存器),因此,我们也为处理器定义了一个数据结构,即结构体vcpu。我们只虚拟了一个vcpu,所以结构体vm中的vcpu数组只包含一个元素。用户空间需要通过文件/dev/kvm与内核中的KVM模块通信,因此定义了一个全局变量g_dev_fd来记录打开的/dev/kvm的文件描述符。
#include <linux/kvm.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> struct vm { int vm_fd; __u64 ram_size; __u64 ram_start; struct kvm_userspace_memory_region mem; struct vcpu *vcpu[1]; }; struct vcpu { int id; int fd; struct kvm_run *run; struct kvm_sregs sregs; struct kvm_regs regs; }; int g_dev_fd;
main函数首先对这些变量进行了初始化,然后调用setup_vm开始组装机器了。组装好机器后,调用load_image加载Guest的镜像到内存中,最后调用run_rm开始执行Guest:
int main(int argc, char **argv) { if ((g_dev_fd = open("/dev/kvm", O_RDWR)) < 0) { fprintf(stderr, "failed to open KVM device.\n"); return -1; } struct vm *vm = malloc(sizeof(struct vm)); struct vcpu *vcpu = malloc(sizeof(struct vcpu)); vcpu->id = 0; vm->vcpu[0] = vcpu; setup_vm(vm, 64000000); load_image(vm); run_vm(vm); return 0; }