深度探索Linux系统虚拟化:原理与实现
上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;
}