溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

QEMU架構(gòu)淺析

發(fā)布時間:2020-07-09 13:21:26 來源:網(wǎng)絡(luò) 閱讀:2081 作者:tasnrh 欄目:云計算

一、QEMU簡介及與KVM等虛擬化的關(guān)系

QEMU是“Quick Emulator”的縮寫,是一個用C語言編寫的開源虛擬化軟件。本文的目的是描述本人所理解的QEMU技術(shù)架構(gòu)的見解,并以此拋磚引玉。眾所周知,QEMU的源代碼開發(fā)文檔非常稀少,描述內(nèi)部結(jié)構(gòu)和工作機理的文檔更是鳳毛麟角,一般的開發(fā)人員想要從事QEMU的開發(fā)工作,通常只能從源代碼入手。因此,對于技術(shù)人員來說,了解QEMU是一項艱巨的任務(wù)。

QEMU有幾種虛擬化模式。首先,它可以使用基于內(nèi)核的虛擬機(KVM)執(zhí)行x86處理器硬件虛擬化,以幾乎比擬硬件本機的速度執(zhí)行運算任務(wù)。其次,它可以通過機器代碼的實時轉(zhuǎn)換來模擬其他處理器以用于虛擬機運行不同平臺的操作系統(tǒng)。最后,它可以使用實時轉(zhuǎn)換為其他架構(gòu)運行簡單的程序,類似于Linux中的Wine。因為QEMU沒有圖形用戶界面(GUI),而其提供的核心能力又是關(guān)鍵而重要的,因此通常用作更復(fù)雜的虛擬化管理器的一部分。比如,我們經(jīng)常使用的開源VirtualBox、Xen等虛擬化產(chǎn)品,其核心底層的虛擬化部分就有集成和使用QEMU,此外,主流的KVM虛擬化也是集成和使用QEMU的主力虛擬化管理器系統(tǒng)。

KVM的角度來說,KVMKernel Virtual Machine)是Linux的一個內(nèi)核驅(qū)動模塊,它能夠讓Linux主機成為一個Hypervisor(虛擬機監(jiān)控器)。在支持VMXVirtual Machine Extension)功能的x86處理器中,Linux在原有的用戶模式和內(nèi)核模式中新增加了客戶模式,并且客戶模式也擁有自己的內(nèi)核模式和用戶模式,虛擬機就是運行在客戶模式中。KVM模塊的職責(zé)就是打開并初始化VMX功能,提供相應(yīng)的接口以支持虛擬機的運行。KVM通過調(diào)用Linux本身內(nèi)核功能,實現(xiàn)對CPU的底層虛擬化和內(nèi)存的虛擬化,使Linux內(nèi)核成為虛擬化層。KVM20072月被導(dǎo)入Linux 2.6.20內(nèi)核中。從存在形式來看,它包括兩個內(nèi)核模塊:kvm.kokvm_intel.ko(或kvm_amd.ko),本質(zhì)上,KVM是管理虛擬硬件設(shè)備的驅(qū)動,該驅(qū)動使用字符設(shè)備/dev/kvm(由KVM本身創(chuàng)建)作為管理接口,主要負(fù)責(zé)vCPU的創(chuàng)建、虛擬內(nèi)存的分配、vCPU寄存器的讀寫以及vCPU的運行。

QEMU的角度來說,QEMUQuick Emulator)本身并不包含或依賴KVM模塊,而是一套由Fabrice Bellard編寫的模擬計算機的自由軟件。QEMU虛擬機是一個純軟件的實現(xiàn),可以在沒有KVM模塊的情況下獨立運行,但是性能比較低。QEMU有整套的虛擬機實現(xiàn),包括處理器虛擬化、內(nèi)存虛擬化以及I/O設(shè)備的虛擬化。在不需要KVM加速的情況下,QEMU通過一個特殊的“重編譯器”對特定的處理器的二進制代碼進行翻譯,從而具有了跨平臺的通用性。QEMU有兩種工作模式:系統(tǒng)模式,可以模擬出整個電腦系統(tǒng),另一種是用戶模式,可以運行不同與當(dāng)前硬件平臺的其他平臺上的程序(比如在x86平臺上運行跑在ARM平臺上的程序)。目前最新版本是4.x。從QEMU角度來看,虛擬機運行期間,QEMU通過KVM模塊提供的系統(tǒng)調(diào)用接口進行內(nèi)核設(shè)置,由KVM模塊負(fù)責(zé)將虛擬機置于處理器的VMX模式運行。QEMU使用了KVM模塊的虛擬化功能,為自己的虛擬機提供硬件虛擬化加速以提高虛擬機的性能。

而現(xiàn)在流行的KVM虛擬化平臺,就是在修改了QEMU代碼,把他模擬CPU、內(nèi)存的代碼換成KVM,而網(wǎng)卡、顯示器等留著,因此QEMU+KVM就成了一個完整的虛擬化平臺。由于KVM運行在內(nèi)核空間,只是內(nèi)核模塊,QEMU運行在用戶空間,實際模擬創(chuàng)建,管理各種虛擬硬件(磁盤,網(wǎng)卡,顯卡等)。從KVM的角度來說,用戶沒法直接跟內(nèi)核模塊交互,需要借助用戶空間的管理工具,因此需要借助QEMU這個運行在用戶空間的工具。KVMQEMU相輔相成,QEMU通過KVM達到了硬件虛擬化的速度,而KVM則通過QEMU來模擬設(shè)備并實現(xiàn)和內(nèi)核空間的KVM的交互,雖然這個交互并不僅僅只有QEMU能夠辦到。此外,由于QEMU模擬IO設(shè)備效率不高的原因,現(xiàn)在常常采用半虛擬化的virtio方式來虛擬IO設(shè)備。

綜上,理解了QEMUKVM的關(guān)系,也就理解了VirtualBox、Xen等虛擬化產(chǎn)品集成和使用QEMU的關(guān)系了。

二、QEMU架構(gòu)及組成

QEMU的架構(gòu)如下圖所示,由幾個基本的組件組成:

QEMU架構(gòu)淺析

QEMU架構(gòu)圖

如圖所示,QEMU由以下幾個部分組成:

l? Hypervisor控制仿真

l? Tiny Code GeneratorTCG)在虛擬機器代碼和宿主機代碼之間進行轉(zhuǎn)換。

l? 軟件內(nèi)存管理單元(MMU)處理內(nèi)存訪問。

l? 磁盤子系統(tǒng)處理不同的磁盤映像格式

l? 設(shè)備子系統(tǒng)處理網(wǎng)卡和其他硬件設(shè)備

下面將對這些組件介紹。

2.1 Hypervisor管理程序

Hypervisor(虛擬機管理程序)是一種創(chuàng)建和運行虛擬機的虛擬機監(jiān)視器。 QEMU中的Hypervisor(虛擬機管理程序)從磁盤映像加載二進制機器代碼,使用TCG將其轉(zhuǎn)換為本機機器代碼,連接到虛擬或?qū)嶋H設(shè)備,并啟動軟件MMU,然后開始在磁盤映像中模擬操作系統(tǒng)。其中,TCG和軟件MMU是實現(xiàn)虛擬化CPU和內(nèi)存的關(guān)鍵。

而集成KVM后,QEMU將使用Linux內(nèi)核的KVM功能以純模式執(zhí)行虛擬機。KVM基本上是Linux內(nèi)核中的Hypervisor(虛擬機管理程序)。它可以并行運行多個操作系統(tǒng)。QEMU可以在KVM中啟動一個新線程以執(zhí)行模擬操作系統(tǒng),然后KVM控制執(zhí)行。從這部分來說,KVMHypervisor(虛擬機管理程序)替換掉了QEMUHypervisor(虛擬機管理程序)。

3.2微代碼生成器(TCG

QEMU中,Tiny Code GeneratorTCG)將源處理器機器代碼轉(zhuǎn)換為虛擬機運行所需的機器代碼塊(如x86機器代碼塊)。從物理硬件的架構(gòu)和角度上來說,不可能在一個處理器上運行為另一個處理器的指令集架構(gòu)(ISA)編譯的機器代碼,例如,x86處理器上的ARM機器代碼。因此,引入中間環(huán)節(jié)對不同的處理器指令集架構(gòu)(ISA)進行翻譯和轉(zhuǎn)換是實現(xiàn)虛擬化通用性的技術(shù)途徑和解決方案。在Tiny Code GeneratorTCG)中,這些已經(jīng)翻譯的代碼塊放在轉(zhuǎn)換緩存中,并通過跳轉(zhuǎn)指令將源處理器的指令集(ISA)和目標(biāo)處理器的指令集(ISA)鏈接在一起。當(dāng)Hypervisor(虛擬機管理程序)在執(zhí)行代碼時,存放于轉(zhuǎn)換緩存中的鏈接指令可以跳轉(zhuǎn)到指定的代碼塊,并且執(zhí)行可以在不同的已翻譯代碼塊上運行,直到需要翻譯新塊為止。在執(zhí)行的過程中,如果遇到了需要翻譯的代碼塊,執(zhí)行動作就會暫停并回會跳回到Hypervisor(虛擬機管理程序),Hypervisor(虛擬機管理程序)就會使用和協(xié)調(diào)TCG對需要進行二進制翻譯的源處理器指令集(ISA)進行轉(zhuǎn)換和翻譯并存儲到轉(zhuǎn)換緩存中。

下圖顯示了QEMUTCG工作原理:

QEMU架構(gòu)淺析

.微代碼生成器工作原理

TCG在運行的過程中存在一個小缺點,即它無法正確運行自修改代碼,因為它沒有將修改后的代碼頁進行標(biāo)記,再次運行時需要重新翻譯。這影響了QEMU的二進制運行效率,從另外一個角度來說,這也增加了一定的安全性。自修改代碼在軟件世界中容易被漏洞利用。特別是緩沖區(qū)溢出攻&擊等內(nèi)存損壞漏洞,這些漏洞利用威脅代理(例如后門)提供的特殊代碼覆蓋易受攻&擊的應(yīng)用程序代碼,如果已經(jīng)被覆蓋的代碼已經(jīng)被運行(并因此被緩存),出了正常運行的會導(dǎo)致漏洞攻&擊利用外,更多的時候則會導(dǎo)致TCG運行和翻譯失敗,從而導(dǎo)致程序復(fù)現(xiàn)異?;虮罎?。

此外,在翻譯的過程中,如果新處理器使用的寄存器多于x86處理器并且具有許多復(fù)雜指令,那么對TCG進行編程以處理和適應(yīng)新的CPU仿真就可能需要大量的工作。目前來說,QEMU所支持的大部分處理器都擁有部分相同的指令集。例如,“MOV”指令幾乎存在于所有處理器中,并且可以簡單地復(fù)制,除非CPU寄存器中存在一些位大小差異。例如,在32位處理器上模擬64位處理器可能需要許多額外的指令,這也需要更多時間在TCG轉(zhuǎn)換器中進行編程。

QEMU的源代碼中,有一個名為'tcg'的子目錄,其中包含將機器指令轉(zhuǎn)換為相應(yīng)的x86機器指令的代碼。此代碼是一個用C編寫的簡單翻譯狀態(tài)機。還有用于內(nèi)存訪問和跳轉(zhuǎn)的特殊轉(zhuǎn)換,因為它們可以生成對軟件內(nèi)存管理單元的調(diào)用。而虛擬化CPU和內(nèi)存也往往是在一起的,因為從本質(zhì)上來說,CPU的工作就是對內(nèi)存的區(qū)域數(shù)據(jù)進行搬運,CPU是內(nèi)存的搬運工。在QEMU保護代碼塊之外的其他內(nèi)存區(qū)域。機器代碼中的跳轉(zhuǎn)和分支也必須到達正確的存儲器地址。

所以通過二進制翻譯技術(shù),針對CPU的仿真和虛擬化就非常簡單了。TCGHypervisor(虛擬機管理程序)能夠?qū)崿F(xiàn)基于CPU的仿真,其中,其CPU仿真流程如下圖所示:

QEMU架構(gòu)淺析

從上圖我們可以看到,針對CPU的仿真和虛擬化其實就是將源處理器的指令集(ISA)轉(zhuǎn)換和翻譯成目標(biāo)處理器的指令集(ISA)。CPU仿真和虛擬化就是通過中間的轉(zhuǎn)換和翻譯來實現(xiàn)的,由此,針對CPU的虛擬化的第一種技術(shù)就完全實現(xiàn)了。這種二進制翻譯技術(shù)是最早的CPU虛擬化技術(shù),誕生了VMware這樣的虛擬化巨頭,也誕生了QEMU這樣的開源虛擬化鼻祖。

?

2.3硬件設(shè)備

虛擬機的硬件設(shè)備要求可以通過直接連接主機中的實際物理設(shè)備或通過QEMU中的硬件設(shè)備仿真來實現(xiàn)。與硬件相關(guān)的大多數(shù)QEMU代碼位于目錄“hw”中。

QEMU中,存在兩種使用硬件設(shè)備的方式:直通模式使用主機實際物理設(shè)備和QEMU的設(shè)備驅(qū)動仿真實現(xiàn)的模擬虛擬設(shè)備。如果采用直通方式使用實際的物理設(shè)備,那么就會搶占主機的設(shè)備使用權(quán),并且其他虛擬機也將無法使用該物理設(shè)備。在直通模式中,虛擬機可以直接訪問USB總線或PCI總線,并可以直接與設(shè)備通信。一般情況下,采用直通模式的物理設(shè)備都是很難進行QEMU仿真的設(shè)備,比如網(wǎng)絡(luò)攝像頭、串行和并行端口等。其他設(shè)備因為大部分虛擬機都會使用,而且很難與主機共享,例如網(wǎng)絡(luò)設(shè)備,因此大都會使用QEMU模擬仿真的虛擬設(shè)備。比如在虛擬機的網(wǎng)絡(luò)設(shè)備中,可通過模擬網(wǎng)卡來解決,從而在網(wǎng)絡(luò)堆棧上添加額外的層。此外,QEMU可以選擇連接到Linux內(nèi)核中的“virtio”半虛擬化驅(qū)動程序,這意味著Linux內(nèi)核處理虛擬機和硬件設(shè)備之間的輸入/輸出,而不采用QEMU的模擬設(shè)備進行中轉(zhuǎn)和傳輸(僅用作中介)。

?

2.4磁盤映像

QEMU可以處理幾種不同的磁盤映像格式。首選格式為rawqcow2。Raw是一種非常簡單的格式,它將文件系統(tǒng)中的字節(jié)逐字節(jié)存儲在文件中。大多數(shù)其他仿真器都支持此格式。Qcow2QEMU自己的圖像格式,對小圖像很有用。并且支持磁盤映像壓縮以及捕獲磁盤映像狀態(tài)的快照。還支持另外兩種格式:在VirtualBox中使用的vdi和在VMWare中使用的vmdk。

QEMU的磁盤映像通過其存儲IO協(xié)議棧來進行支持,其存儲協(xié)議棧如下圖所示:

QEMU架構(gòu)淺析

QEMU架構(gòu)淺析

QEMU存儲協(xié)議棧

從QEMU的存儲協(xié)議棧來說,應(yīng)用程序和虛擬機內(nèi)核的工作類似于裸機。虛擬機通過仿真硬件與QEMU交互,并將IO執(zhí)行情況的控制流和數(shù)據(jù)流交互給QEMUQEMU代表虛擬機對磁盤鏡像文件執(zhí)行I / O操作。而從主機內(nèi)核層面上,主機內(nèi)核會將虛擬機I / O視為一種用戶空間的應(yīng)用程序IO請求進行正常的執(zhí)行處理。

2.5軟件MMU

傳統(tǒng)處理器中的內(nèi)存管理單元(MMU)處理對計算機內(nèi)存位置的訪問。當(dāng)處理器想要訪問某個存儲器地址時,MMU獲取該地址的內(nèi)容。此內(nèi)容可以來自處理器芯片上的本地快速緩存,來自隨機存取存儲器(RAM)或來自光盤。它甚至可以做出一些關(guān)于緩存某些內(nèi)存位置的控制決定。

QEMU有一個基于軟件的MMU,其工作方式與硬件MMU類似。它使用地址轉(zhuǎn)換緩存,其中包含訪客地址、主機地址和偏移值,以提高轉(zhuǎn)換速度。它還允許智能鏈接代碼塊,以便在沒有內(nèi)存故障的情況下實現(xiàn)更快的執(zhí)行,其中必須重新加載和重新轉(zhuǎn)換內(nèi)存塊。

在尋找在QEMU中運行的虛擬機的漏洞時,軟件MMU是否正在進行翻譯和正確放置塊會是其測試和Fuzz的重點。

三、總結(jié)

其實搞清楚QEMU的技術(shù)架構(gòu)和實現(xiàn)細(xì)節(jié),我們需要弄明白QEMU的架構(gòu)和組成,以及每個組件的作用及運行機制。此外,我們還需要了解每個組成組件之間的相互交互關(guān)系,從數(shù)據(jù)流的角度來看,其主要是控制流和數(shù)據(jù)流;從IO角度來看,其主要是網(wǎng)絡(luò)IO和存儲IO,從技術(shù)實現(xiàn)機制來看,其主要是虛擬化CPU和內(nèi)存以及存儲、網(wǎng)絡(luò)協(xié)議棧的實現(xiàn)。本文有許多的未盡事宜,待請后續(xù)補充。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI