KVM架構與原理詳解

1.KVM架構

KVM 基本上有兩個組件構成:架構

1.  kvm 驅動  如今已是Linux內核的一個模塊了,它的做用主要是負責虛擬機的建立,虛擬內存的分配 虛擬CPU寄存器的讀寫和虛擬cpu的運行函數

2.  另外一個組件是 Qemu    QEMU是一個通用的開源機器模擬器和虛擬器,其主要的功能是用於模擬虛擬機的用戶空間組件,提供io 設備模型,訪問外設的途徑oop

 

Qemu 是什麼?性能

 Qemu 是純軟件設計的虛擬化模擬器,幾乎能夠模擬任何硬件設備,咱們最熟悉的就是可以模擬一臺可以獨立運行操做系統的虛擬機,虛擬機認爲本身和虛擬機打交道,但實際上是和Qemu模擬出來的硬件打交道,Qemu 將這些真正的指令轉譯給真正的硬件ui

正由於Qemu是純軟件實現的,全部的指令都要通過qemu過一手,性能很是低,因此,在生產環境中,因此在生產環境中,Qemu配合KVM來完成虛擬化工做,由於kvm是硬件輔助的虛擬化技術,主要負責比較繁瑣的cpu虛擬化和內存虛擬化,而QEMU則負責IO設備虛擬化,二者合做發揮自身的優點,相得益彰spa

 

從本質上看,虛擬出的每一個虛擬機對應宿主機上的一個QEMU 進程,而虛擬機的執行線路(cpu線路,io線路)對用qemu 進程中的一個線程,操作系統

下面經過啓動一個虛擬機來說解kvm 與QEmu是怎麼交互工做的線程

// 第一步,獲取到 KVM 句柄翻譯

 kvmfd = open("/dev/kvm", O_RDWR);設計

// 第二步,建立虛擬機,獲取到虛擬機句柄。

 vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);

// 第三步,爲虛擬機映射內存,還有其餘的 PCI,信號處理的初始化。

    ioctl(kvmfd, KVM_SET_USER_MEMORY_REGION, &mem);

// 第四步,將虛擬機鏡像映射到內存,至關於物理機的 boot 過程,把鏡像映射到內存。

// 第五步,建立 vCPU,併爲 vCPU 分配內存空間。 

ioctl(kvmfd, KVM_CREATE_VCPU, vcpuid);

vcpu->kvm_run_mmap_size = ioctl(kvm->dev_fd, KVM_GET_VCPU_MMAP_SIZE, 0); // 第五步,建立 vCPU 個數的線程並運行虛擬機。

 ioctl(kvm->vcpus->vcpu_fd, KVM_RUN, 0);

 // 第六步,線程進入循環,並捕獲虛擬機退出緣由,作相應的處理。 

for (;;) { ioctl(KVM_RUN) switch (exit_reason) {

 case KVM_EXIT_IO: /* ... */ case KVM_EXIT_HLT: /* ... */ 

} }

// 這裏的退出並不必定是虛擬機關機, 

// 虛擬機若是遇到 I/O 操做,訪問硬件設備,缺頁中斷等都會退出執行,

// 退出執行能夠理解爲將 CPU 執行上下文返回到 Qemu。

 

Qemu 軟件實現虛擬化的思路是二進制指令翻譯技術,主要是提取客戶端的代碼指令,而後將其翻譯成TCG中間代碼,最後再將中間代碼 翻譯成物理機指定架構的代碼,如X86體系就翻譯成其支持的代碼形式,ARM架構同理,

因此,從宏觀上看,源碼結構主要包含如下幾個部分:

· /vl.c:最主要的模擬循環,虛擬機環境初始化,和 CPU 的執行。

· /target-arch/translate.c:將 guest 代碼翻譯成不一樣架構的 TCG 操做碼。

· /tcg/tcg.c:主要的 TCG 代碼。

· /tcg/arch/tcg-target.c:將 TCG 代碼轉化生成主機代碼。

· /cpu-exec.c:主要尋找下一個二進制翻譯代碼塊,若是沒有找到就請求獲得下一個代碼塊,而且操做生成的代碼塊。

 

其中,涉及的主要幾個函數以下:

函數

路徑

註釋

main_loop

{/vl.c}

不少條件的判斷,如電源是否斷等

qemu_main_loop_start

{/cpus.c}

分時運行 CPU 核

struct CPUState

{/target-xyz/cpu.h}

CPU 狀態結構體

cpu_exec

{/cpu-exec.c}

主要的執行循環

struct TranslationBlock

{/exec-all.h}

TB(二進制翻譯代碼塊) 結構體

cpu_gen_code

{translate-all.c}

初始化真正代碼生成

tcg_gen_code

{/tcg/tcg.c}

tcg 代碼翻譯成 host 代碼

知道了這個整體的代碼結構,再去具體瞭解每個模塊可能會相對容易一點。 

            

 

 KVM做用

kvm基本結構

Kvm 已是內核模塊,被看做是一個標準的Linux字符集設備 /dev/kvm

Qemu 經過kvmlib接口,用fd 經過ioctl 向設備驅動來發送建立,運行虛擬機命令,設備驅動/dev/kvm 就會來解析命令(kvm_dev_ioctl 在函數kvm_main.c中)

如下爲kvm_dev_ioctl函數 執行的整個代碼流程:

 

Kvm 模塊讓Linux 主機成爲一個虛擬機監視/管理器(VMM),而且在原有的Linux 兩種執行模式的基礎上,新增長了客戶模式,客戶模式擁有本身的用戶模式和內核模式,在虛擬機運行時,

三種運行模式分別爲:

內核模式: 實現客戶模式的切換,處理由於IO或者其餘指令引發的客戶模式退出(VM_EXIT) kvm 工做在                  這 個模式下,

用戶模式:表明用戶在IO模式下,執行QEMU 指令;

客戶模式:執行非IO的客戶代碼,虛擬機運行在這種模式下

 

在kvm的模型中,每個guest os 都是做爲一個標準的Linux進程,均可以使用Linux進程管理管理命令!

這裏假如Qemu 經過ioctl 發出KVM_CREAT_VM指令,建立一個VM後,qemu須要發送一個命令給VM,如KVM_CREAT_VCPU,這些命令固然也是經過ioctl發送的,用戶程序中用ioctl經過發送KVM_CREAT_VM 指令後獲得的返回值就是fd(KVM_VM),fd是建立的指向特定虛擬機實例的文件描述符,以後利用這個fd發送命令給VM進行訪問控制。KVM 解析這些命令kvm_vm_ioctl

2.KVM工做原理

 Kvm 工做原理的基本闡釋:

用戶模式的qume利用libkvm 經過ioctl進入內核模式,kvm 模塊爲虛擬機建立虛擬內存,虛擬cpu後執行VMLUACH指令進入客戶模式。加載guest os並執行。若是guest os 發生外部中斷,或者影子頁表缺頁之類的狀況,會暫停guest os的執行,退出客戶模式出行異常處理,以後從新進入客戶模式,執行客戶代碼,若是發生iO事件或者信號隊列中有信號到達,就會進入用戶模式處理。

處理狀況以下圖

 

 

什麼是虛擬機管理器vmm ,虛擬機管理器(vmm)有哪些,區別是什麼?

虛擬機管理器(virtual machine monitor)是一個宿主程序,它支持一臺計算機執行多個徹底相同的執行環境,每位用戶都會感受本身在一臺獨立的計算機上,與其餘用戶相隔離的計算機上操做,儘管事實上爲每位用戶提供服務的都是同一臺機器,在此種狀況下,一臺虛擬機就是由一個潛在的控制程序管理的操做系統

 

Vmm 是在底層對其上的虛擬機的管理和支持,之前的虛擬機必須如今一個做系統上安裝虛擬機操做軟件,而後再在操做軟件上安裝虛擬機,安裝系統和應用。但如今的intel 的cpu 已經對虛擬化技術作了硬件支持,大多數的vmm可直接裝在裸機上,在其上在安裝幾個虛擬機,這樣就大大提高了虛擬化環境下的性能體驗

相關文章
相關標籤/搜索