接前一篇文章:
本文内容参考:
《 QEMU / KVM 》源码解析与应用 —— 李强,机械工业出版社
《深度探索 Linux 系统 虚拟化 原理与实现》—— 王柏生 谢广军, 机械工业出版社
特此致谢!
三、KVM模块初始化介绍
1. KVM简介与 源码 组织结构
KVM全称为 Kernel-Based Virtual Machine ,中文译为 基于内核的虚拟化技术 。KVM是由 以色列初创公司Qumranet 在CPU推出硬件虚拟化之后开发的一个基于内核的 虚拟机监控器 。KVM的架构简单清晰,充分地重用了内核的诸多功能,因此得以快速进入内核,随着Red Hat收购Qumranet,KVM得到了更大的支持与发展。
KVM在Linux内核树中的代码组织(KVM源码目录结构)如下图所示:
KVM时一个虚拟化的统称方案,除x86外,arm等其它架构也有自己的方案,因此KVM的主体代码位于Linux内核树virt/kvm目录下面,表示所有CPU架构的公共代码(通用代码),这也是内核kvm.ko对应的源码。
CPU体系结构相关代码位于arch目录下面,如x86架构相关的代码在arch/x86/kvm/下。
当然,即使是同一架构也可能会有多种不同的实现。例如,KVM就有Intel和AMD两家的实现(当然,实际不止这两家),所以在x86目录下面就有多种实现代码。如Intel的vmx目录(对应Intel VM-X 方案)、AMD的svm目录(对应AMD-V方案)。ioapic.c和lapic.c是中断控制器的代码,这也是intel-kvm.ko和amd-kvm.ko的来源。
KVM的所有虚拟化实现(Intel和AMD)都会向KVM模块注册一个kvm_x86_ops结构,这样,KVM中的一些函数就是一个外壳,其可能首先会调用kvm_arch_xxx函数,表示的是调用CPU架构相关的函数。而如果kvm_arch_xxx函数需要调用到实现相关的代码,则会调用kvm_x86_ops结构中的各相关回调函数。下边以x86架构中的Intel实现为例进行分析和讲解。
使用KVM需要加载kvm.ko和kvm-intel.ko两个内核模块。
- kvm.ko
kvm.ko是由KVM的通用代码生成的 。kvm.ko初始化代码不做任何事情,只是相当于把代码加到了内存中。
- kvm-intel.ko
kvm-intel.ko模块则是由Intel CPU架构相关的代码生成的 。KVM的开启和关闭都是由kvm-intel.ko完成的。
KVM初始化完成后,会向用户空间呈现KVM的接口,这些接口都是由kvm.ko导出的。用户空间程序调用这些接口时,kvm.ko中的通用代码反过来会调用kvm-intel.ko架构中的相关(相应)代码。调用关系如下图所示:
更多内容请看下回。