资源预览内容
第1页 / 共20页
第2页 / 共20页
第3页 / 共20页
第4页 / 共20页
第5页 / 共20页
第6页 / 共20页
第7页 / 共20页
第8页 / 共20页
第9页 / 共20页
第10页 / 共20页
亲,该文档总共20页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
KVM 虚拟机源代码分析虚拟机源代码分析1,KVM 结构及工作原理结构及工作原理1.1KVM 结构结构KVM 基本结构有两部分组成。一个是 KVM Driver ,已经成为 Linux 内核的一个模块。 负责虚拟机的创建,虚拟内存的分配,虚拟 CPU 寄存器的读写以及虚拟 CPU 的运行等。另 外一个是稍微修改过的 Qemu,用于模拟 PC 硬件的用户空间组件,提供 I/O 设备模型以及 访问外设的途径。VMM(Linux 内核+ KVM Driver)Linux内核 模式Linux用户 模式/dev/kvmKvm-vm fd Kvm-vcpu fdKVM fdioctlLibKvmQemu客户模式内核模式用户模式图 1 KVM 基本结构 KVM 基本结构如图 1 所示。其中 KVM 加入到标准的 Linux 内核中,被组织成 Linux 中标准 的字符设备(/dev/kvm)。Qemu 通 KVM 提供的 LibKvm 应用程序接口,通过 ioctl 系统调用创 建和运行虚拟机。KVM Driver 使得整个 Linux 成为一个虚拟机监控器。并且在原有的 Linux 两种执行模式(内核模式和用户模式)的基础上,新增加了客户模式,客户模式拥有自己的 内核模式和用户模式。在虚拟机运行下,三种模式的分工如下: 客户模式:执行非 I/O 的客户代码。虚拟机运行在客户模式下。 内核模式:实现到客户模式的切换。处理因为 I/O 或者其它指令引起的从客户模式的退出。 KVM Driver 工作在这种模式下。 用户模式:代表客户执行 I/O 指令 Qemu 运行在这种模式下。在 KVM 模型中,每一个 Guest OS 都作为一个标准的 Linux 进程,可以使用 Linux 的进程管 理指令管理。 在图 1 中./dev/kvm 在内核中创建的标准字符设备,通过 ioctl 系统调用来访问内核虚 拟机,进行虚拟机的创建和初始化;kvm_vm fd 是创建的指向特定虚拟机实例的文件描述 符,通过这个文件描述符对特定虚拟机进行访问控制;kvm_vcpu fd 指向为虚拟机创建的虚 拟处理器的文件描述符,通过该描述符使用 ioctl 系统调用设置和调度虚拟处理器的运行。1.2KVM 工作原理工作原理KVM 的基本工作原理:用户模式的 Qemu 利用接口 libkvm 通过 ioctl 系统调用进入内 核模式。KVM Driver 为虚拟机创建虚拟内存和虚拟 CPU 后执行 VMLAUCH 指令进入客户模 式。装载 Guest OS 执行。如果 Guest OS 发生外部中断或者影子页表缺页之类的事件,暂停 Guest OS 的执行,退出客户模式进行一些必要的处理。然后重新进入客户模式,执行客户 代码。如果发生 I/O 事件或者信号队列中有信号到达,就会进入用户模式处理。KVM 采用 全虚拟化技术。客户机不用修改就可以运行。开始用户模式 Qemu内核模式KVM Driver客户模式Guest OS执行IOCTL系统调 用处理I/O进入客户模式处理退出执行客户代码VMX Root OperationVMX Non Root OperationI/O?信号到 达N NO OY Ye es s图 2 KVM 工作基本原理2 ,相关技术,相关技术-处理器管理和硬件辅助虚拟化技术处理器管理和硬件辅助虚拟化技术Intel 在 2006 年发布了硬件虚拟化技术。其中支持 X86 体系结构的称为 Intel VT-x 技术。 ADM 称为 SVM 技术。 VT-x 引入了一种新的处理器操作,叫做 VMX(Virtual Machine Extension) ,提供了两种 处理器的工作环境。VMCS 结构实现两种环境之间的切换。VM Entry 使虚拟机进去客户模 式,VM Exit 使虚拟机退出客户模式。2.1KVM 中中 Guest OS 的调度执行的调度执行VMM 调度 Guest OS 执行时,Qemu 通过 ioctl 系统调用进入内核模式,在 KVM Driver 中通过 get_cpu 获得当前物理 CPU 的引用。之后将 Guest 状态从 VMCS 中读出。并装入物 理 CPU 中。执行 VMLAUCH 指令使得物理处理器进入非根操作环境,运行客户代码。 当 Guest OS 执行一些特权指令或者外部事件时,比如 I/O 访问,对控制寄存器的操作, MSR 的读写数据包到达等。都会导致物理 CPU 发生 VMExit,停止运行 Guest OS。将 Guest OS 保存到 VMCS 中,Host 状态装入物理处理器中,处理器进入根操作环境,KVM 取得控 制权,通过读取 VMCS 中 VM_EXIT_REASON 字段得到引起 VM Exit 的原因。从而调用 kvm_exit_handler 处理函数。如果由于 I/O 获得信号到达,则退出到用户模式的 Qemu 处理。 处理完毕后,重新进入客户模式运行虚拟 CPU。如果是因为外部中断,则在 Lib KVM 中做 一些必要的处理,重新进入客户模式执行客户代码。2.2KVM 中内存管理中内存管理KVM 使用影子页表实现客户物理地址到主机物理地址的转换。初始为空,随着虚拟机 页访问实效的增加,影子页表被逐渐建立起来,并随着客户机页表的更新而更新。在 KVM 中提供了一个哈希列表和哈希函数,以客户机页表项中的虚拟页号和该页表项所在页表的 级别作为键值,通过该键值查询,如不为空,则表示该对应的影子页表项中的物理页号已 经存在并且所指向的影子页表已经生成。如为空,则需新生成一张影子页表,KVM 将获取 指向该影子页表的主机物理页号填充到相应的影子页表项的内容中,同时以客户机页表虚 拟页号和表所在的级别生成键值,在代表该键值的哈希桶中填入主机物理页号,以备查询。 但是一旦 Guest OS 中出现进程切换,会把整个影子页表全部删除重建,而刚被删掉的页表 可能很快又被客户机使用,如果只更新相应的影子页表的表项,旧的影子页表就可以重用。 因此在 KVM 中采用将影子页表中对应主机物理页的客户虚拟页写保护并且维护一张影子页 表的逆向映射表,即从主机物理地址到客户虚拟地址之间的转换表,这样 VM 对页表或页 目录的修改就可以触发一个缺页异常,从而被 KVM 捕获,对客户页表或页目录项的修改就 可以同样作用于影子页表,通过这种方式实现影子页表与客户机页表保持同步。2.3KVM 中设备管理中设备管理一个机器只有一套 I/o 地址和设备。设备的管理和访问是操作系统中的突出问题、同 样也是虚拟机实现的难题,另外还要提供虚拟设备供各个 VM 使用。在 KVM 中通过移植 Qemu 中的设备模型(Device Model)进行设备的管理和访问。操作系统中,软件使用可编程 I/O(PIO)和内存映射 I/O(MMIO)与硬件交互。而且硬件可以发出中断请求,由操作系 统处理。在有虚拟机的情况下,虚拟机必须要捕获并且模拟 PIO 和 MMIO 的请求,模拟虚 拟硬件中断。 捕获 PIO:由硬件直接提供。当 VM 发出 PIO 指令时,导致 VM Exit 然后硬件会将 VM Exit 原因及对应的指令写入 VMCS 控制结构中,这样 KVM 就会模拟 PIO 指令。MMIO 捕获: 对 MMIO 页的访问导致缺页异常,被 KVM 捕获,通过 X86 模拟器模拟执行 MMIO 指令。 KVM 中的 I/O 虚拟化都是用户空间的 Qemu 实现的。所有 PIO 和 MMIO 的访问都是被转发 到 Qemu 的。Qemu 模拟硬件设备提供给虚拟机使用。KVM 通过异步通知机制以及 I/O 指 令的模拟来完成设备访问,这些通知包括:虚拟中断请求,信号驱动机制以及 VM 间的通 信。 以虚拟机接收数据包来说明虚拟机和设备的交互。图 3 I/O 分析 (1)当数据包到达主机的物理网卡后,调用物理网卡的驱动程序,在其中利用 Linux 内核中 的软件网桥,实现数据的转发。 (2)在软件网挢这一层,会判断数据包是发往那个设备的,同时调用网桥的发送函数,向对 应的端口发送数据包。 (3)若数据包是发往虚拟机的,则要通过 tap 设备进行转发,tap 设备由两部分组成,网络设 备和字符设备。网络设备负责接收和发送数据包,字符设备负责将数据包往内核空间和用 户空间进行转发。Tap 网络部分收到数据包后,将其设备文件符置位,同时向正在运行 VM 的进程发出 I/O 可用信号,引起 VM Exit,停止 VM 运行,进入根操作状态。KVM 根据 KVM_EXIT_REASON 判断原因,模拟 I/O 指令的执行,将中断注入到 VM 的中断向量表中。 (4)返回用户模式的 Qemu 中,执行设备模型。返回到 kvm_main loop 中,执行 Kvmmainloopwait,之后进入 main_loop wait 中,在这个函数里收集对应设备的设备文件描 述符的状态,此时 tap 设备文件描述符的状态同样被集到 fd set。(5)Kvm mainloop 不停地循环,通过 select 系统调用判断哪螋文件描述符的状态发生变化, 相应的调用对应的处理函数。对予 tap 来说,就会通过 Qemusend_packet 将数据发往 rtl8139 一 doreceiver,在这个函数中完成相当于硬件 RTL8139 网卡的逻辑操作。KVM 通 过模拟 IO 指令操作虚拟 RTL8139 将数据拷贝到用户地址空间,放在相应的 IO 地址。 用户模式处理完毕后返回内核模式,而后进入客户模式,VM 被再次执行,继续收发数据 包。3,KVM 源代码分析源代码分析-虚拟机创建和运行流程代码分析虚拟机创建和运行流程代码分析3.1 KVM 创建和运行虚拟机流程创建和运行虚拟机流程KVM 虚拟机创建和运行虚拟机分为用户态和核心态两个部分,用户态主要提供应用程 序接口,为虚拟机创建虚拟机上下文环境,在 libkvm 中提供访问内核字符设备/dev/kvm 的 接口;内核态为添加到内核中的字符设备/dev/kvm,模块加载进内核后即可进行接口用户 空间调用创建虚拟机。在创建虚拟机过程中,kvm 字符设备主要为客户机创建 kvm 数据机 构,创建该虚拟机的虚拟机文件描述符及其相应的数据结构以及创建虚拟处理器及其相应 的数据结构。Kvm 创建虚拟机的流程如图 4 所示。 首先申明一个 kvm_context_t 变量用以描述用户态虚拟机上下文信息,然后调用 kvm_init()函数初始化虚拟机上下文信息;函数 kvm_create()创建虚拟机实例,该函数通过 ioctl 系统调用创建虚拟机相关的内核数据结构并且返回虚拟机文件描述符给用户态 kvm_context_t 数据结构;创建完内核虚拟机数据结构后,再创建内核 pit 以及 mmio 等基 本外设模拟设备,然后调用 kvm_create_vcpu()函数来创建虚拟处理器,kvm_create_vcpu() 函数通过 ioctl()系统调用向由 vm_fd 文件描述符指向的虚拟文件调用创建虚拟处理器,并 将虚拟处理器的文件描述符返回给用户态程序,用以以后的调度使用;创建完虚拟处理器 后,由用户态的 QEMU 程序申请客户机用户空间,用以加载和运行客户机代码;为了使得 客户虚拟机正确执行,必须要在内核中为客户机建立正确的内存映射关系,即影子页表信 息。因此,申请客户机内存地址空间后,调用函数 kvm_create_phys_mem()创建客户机内 存映射关系,该函数主要通过 ioctl 系统调用向 vm_fd 指向的虚拟文件调用设置内核数据结 构中客户机内存域相关信息,主要建立影子页表信息;当创建好虚拟处理器和影子页表后, 即可读取客户机到指定分配的空间中,然后调度虚拟处理器运行。调度虚拟机的函数为 kvm_run(),该函数通过 ioctl 系统调用调用由虚拟处理器文件描
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号