KVM
KVM(Kernel-based Virtual Machine)基于内核的虚拟机,是linux内核的一个模块,正是由于这个模块的存在,linux才具有了Hypervisor的能力,现在我们说的KVM一般不单单指linux的KVM模块,而是包含了Qemu的。其实Qemu本身就是完整的虚拟化方案了,包括处理器、内存及各种虚拟设备的模拟,但是由于他是纯软件的虚拟化,所以性能较低,KVM集成了简化版的Qemu,自身主要负责模拟CPU和内存,而把I/O设备,用户空间交给Qemu来处理,二者共同构成了完整的虚拟化解决方案。
虚机运行包含三种模式,即:客户模式,用户模式和内核模式。客户模式可以理解为运行在KVM限制的CPU模式下的GuestOS所在的模式,它又包含用户模式和内核模式;用户模式为用户提供虚拟机管理的用户空间工具以及代表用户执行I/O,Qemu运行在这个模式之下;内核模式实现客户模式的切换,处理因为I/O或者其他指令引起的从客户模式退出,KVM模块工作在这个模式下。
KVM是虚机的核心部分,其主要功能是初始化CPU 硬件,内存的虚拟化以及虚拟机IO指令的拦截,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚机的运行提供一定的支持。KVM中,虚拟机被实现为常规的Linux进程,由标准Linux调度程序进行调度;虚机的每个虚拟CPU被实现为一个常规的Linux线程,这使得KVM能够使用Linux内核的已有功能。
KVM本身不执行任何设备模拟,需要Qemu通过/dev/kvm接口设置一个GuestOS的地址空间,向它提供模拟的I/O设备,并将它的视频显示映射回宿主机的显示屏。/dev/kvm的设备是由KVM生成的,有了/dev/kvm设备,使得GuestOS的地址空间(内存地址、磁盘地址)能够独立于标准内核或其他任何GuestOS的地址空间。每个打开/dev/kvm设备的不同的进程或线程,所能使用的都是唯一且各不相同的地址映射,KVM内核模块通过/dev/kvm设备提供了内存虚拟化,给予GuestOS与内核或者其他GuestOS相对独立的地址空间。每个GuestOS都有自己的地址空间,并且这些地址空间是在实例化GuestOS时创建映射的。映射给GuestOS的物理内存实际上是映射给这个GuestOS在VMM中相应进程的虚拟内存。
虚机的创建和运行是Qemu和KVM相互配合的过程,前面说过,Qemu工作在用户模式,指令是用户模式发出的,Qemu通过libkvm调用IOCTL(设备I/O通道管理程序)进入内核模式,Qemu通过IOCTL发出KVM_CREATE_VM 指令,返回一个文件描述符,之后就通过该fd进行虚机的管理,之后Qemu通过fd继续发送KVM_CREATE_VCPU等命令,进行cpu和内存等的虚拟化,其中KVM会返回Qemu通过/dev/kvm接口设置一个客户机虚拟服务器的地址空间,完成后执行VMLAUNCH指令进入客户模式,装载GuestOS并运行。当GuestOS产生I/O指令后,KVM会截获请求交给并Qemu,Qemu工作在用户模式,当虚机进行I/O操作时,KVM会从上次系统调用出口处返回Qemu,由Qemu来负责解析和模拟这些设备。