快速上手QEMU:創(chuàng)建你的第一個(gè)虛擬機(jī)實(shí)例
在計(jì)算機(jī)技術(shù)的廣闊天地中,虛擬化技術(shù)無(wú)疑是一顆璀璨的明星,為我們的計(jì)算環(huán)境帶來(lái)了前所未有的靈活性和效率。而在虛擬化的眾多工具和技術(shù)中,Qemu 虛擬機(jī)管理器以其獨(dú)特的魅力和強(qiáng)大的功能,吸引著無(wú)數(shù)技術(shù)愛(ài)好者和專(zhuān)業(yè)人士的目光;Qemu,全稱 Quick Emulator,是一款開(kāi)源的虛擬機(jī)監(jiān)視器。它誕生于 2003 年,由 Fabrice Bellard 發(fā)起開(kāi)發(fā) ,最初的目標(biāo)是提供一個(gè)通用的模擬器和虛擬化工具。經(jīng)過(guò)多年的發(fā)展和開(kāi)源社區(qū)的積極貢獻(xiàn),Qemu 已經(jīng)從一個(gè)簡(jiǎn)單的項(xiàng)目,成長(zhǎng)為一款功能強(qiáng)大且備受歡迎的虛擬機(jī)軟件,被廣泛應(yīng)用于開(kāi)發(fā)、測(cè)試、實(shí)驗(yàn)以及云計(jì)算等眾多領(lǐng)域。
從本質(zhì)上講,Qemu是一種高效的硬件模擬器,它能夠在軟件中模擬完整的機(jī)器,包括各種硬件設(shè)備,如CPU、內(nèi)存、硬盤(pán)、網(wǎng)卡等 。這意味著,通過(guò)Qemu,我們可以在一臺(tái)物理計(jì)算機(jī)上創(chuàng)建多個(gè)虛擬的計(jì)算機(jī)環(huán)境,每個(gè)環(huán)境都可以運(yùn)行不同的操作系統(tǒng)和應(yīng)用程序,就像它們運(yùn)行在真實(shí)的物理機(jī)器上一樣。
而且,Qemu 支持多種處理器架構(gòu)的模擬和虛擬化,如 x86、ARM、PowerPC、SPARC 等 。這種跨架構(gòu)的模擬能力,使得 Qemu 在不同的硬件平臺(tái)和應(yīng)用場(chǎng)景中都能發(fā)揮重要作用,無(wú)論是進(jìn)行 x86 架構(gòu)的服務(wù)器虛擬化,還是進(jìn)行 ARM 架構(gòu)的嵌入式系統(tǒng)開(kāi)發(fā),Qemu 都能提供有力的支持。
一、Qemu簡(jiǎn)介
1.1 Qemu概述
Qemu 是一款開(kāi)源的硬件模擬器和虛擬機(jī)監(jiān)控器,其全稱為 Quick Emulator,即快速模擬器 。它允許用戶在一臺(tái)物理計(jì)算機(jī)上創(chuàng)建和運(yùn)行多個(gè)虛擬機(jī),每個(gè)虛擬機(jī)都可以運(yùn)行不同的操作系統(tǒng),就像它們?cè)讵?dú)立的物理計(jì)算機(jī)上運(yùn)行一樣。Qemu 的特別之處在于,它不僅能夠模擬常見(jiàn)的 x86 架構(gòu),還對(duì) ARM、PowerPC、MIPS、RISC-V 等多種硬件架構(gòu)提供了出色的支持。
這使得開(kāi)發(fā)者可以在 x86 架構(gòu)的主機(jī)上,輕松模擬運(yùn)行 ARM 架構(gòu)的操作系統(tǒng)和應(yīng)用程序,為跨平臺(tái)開(kāi)發(fā)和測(cè)試提供了極大的便利。例如,在開(kāi)發(fā)基于 ARM 架構(gòu)的嵌入式系統(tǒng)時(shí),開(kāi)發(fā)者可以利用 Qemu 在普通的 PC 上搭建模擬環(huán)境,進(jìn)行代碼編寫(xiě)、調(diào)試和測(cè)試,大大降低了開(kāi)發(fā)成本和時(shí)間。
從功能實(shí)現(xiàn)角度來(lái)看,Qemu 通過(guò)軟件的方式模擬硬件設(shè)備的行為。當(dāng)虛擬機(jī)中的操作系統(tǒng)執(zhí)行指令時(shí),Qemu 會(huì)將這些指令轉(zhuǎn)換為宿主機(jī)能夠理解的指令并執(zhí)行,同時(shí)模擬硬件設(shè)備的響應(yīng),使得虛擬機(jī)中的操作系統(tǒng)感覺(jué)像是在真實(shí)的硬件上運(yùn)行。這種模擬機(jī)制使得 Qemu 具有極高的通用性和靈活性,幾乎可以運(yùn)行任何操作系統(tǒng)和應(yīng)用程序。
用戶可以通過(guò)不同Linux發(fā)行版所帶有的軟件包管理器來(lái)安裝QEMU。如在Debian系列的發(fā)行版上可以使用下面的命令來(lái)安裝:
sudo apt-get install qemu
除此之外,也可以選擇從源碼安裝。
1.2Qemu源碼安裝流程
(1)獲取QEMU源碼,可以從QEMU下載官網(wǎng)上下載QEMU源碼的tar包,以命令行下載2.0版本的QEMU為例:
$wget http://wiki.qemu-project.org/download/qemu-2.0.0.tar.bz2
$tar xjvf qemu-2.0.0.tar.bz2
(2)編譯及安裝,獲取源碼后,可以根據(jù)需求來(lái)配置和編譯QEMU:
$cd qemu-2.0.0 //如果使用的是git下載的源碼,執(zhí)行cd qemu
$./configure --enable-kvm --enable-debug --enable-vnc --enable-werror --target-list="x86_64-softmmu"
或者用戶模式(使能TCI)$./configure --target-list=arm-linux-user --enable-tcg-interpreter
$make -j8
$sudo make install
configure腳本用于生成Makefile,其選項(xiàng)可以用./configure --help查看。這里使用到的選項(xiàng)含義如下:
--enable-kvm:編譯KVM模塊,使QEMU可以利用KVM來(lái)訪問(wèn)硬件提供的虛擬化服務(wù)。
--enable-vnc:?jiǎn)⒂肰NC。
--enalbe-werror:編譯時(shí),將所有的警告當(dāng)作錯(cuò)誤處理。
--target-list:選擇目標(biāo)機(jī)器的架構(gòu)。默認(rèn)是將所有的架構(gòu)都編譯,但為了更快的完成編譯,指定需要的架構(gòu)即可。
安裝好之后,會(huì)生成如下應(yīng)用程序:
圖片
- ivshmem-client/server:這是一個(gè) guest 和 host 共享內(nèi)存的應(yīng)用程序,遵循 C/S 的架構(gòu)。
- qemu-ga:這是一個(gè)不利用網(wǎng)絡(luò)實(shí)現(xiàn) guest 和 host 之間交互的應(yīng)用程序(使用 virtio-serial),運(yùn)行在 guest 中。
- qemu-io:這是一個(gè)執(zhí)行 Qemu I/O 操作的命令行工具。
- qemu-system-x86_64:Qemu 的核心應(yīng)用程序,虛擬機(jī)就由它創(chuàng)建的。
- qemu-img:創(chuàng)建虛擬機(jī)鏡像文件的工具,下面有例子說(shuō)明。
- qemu-nbd:磁盤(pán)掛載工具。
1.3常用命令與操作示例
⑴創(chuàng)建虛擬機(jī)磁盤(pán)鏡像:在使用 Qemu 創(chuàng)建虛擬機(jī)之前,需要先創(chuàng)建一個(gè)虛擬磁盤(pán)鏡像,用于存儲(chǔ)虛擬機(jī)的操作系統(tǒng)和數(shù)據(jù) 。可以使用qemu-img工具來(lái)創(chuàng)建磁盤(pán)鏡像 。例如,要?jiǎng)?chuàng)建一個(gè)大小為 20GB,格式為 qcow2 的磁盤(pán)鏡像文件 “myvm.qcow2”,可以在命令行中輸入以下命令:
qemu-img create -f qcow2 myvm.qcow2 20G
其中,-f參數(shù)指定磁盤(pán)鏡像的格式,qcow2是一種常用的磁盤(pán)鏡像格式,具有寫(xiě)時(shí)復(fù)制等特性,可以有效節(jié)省磁盤(pán)空間 。myvm.qcow2是磁盤(pán)鏡像文件的名稱,20G表示磁盤(pán)鏡像的大小為 20GB 。
⑵啟動(dòng)虛擬機(jī):創(chuàng)建好磁盤(pán)鏡像后,就可以使用qemu-system-x86_64命令來(lái)啟動(dòng)虛擬機(jī) 。假設(shè)要啟動(dòng)剛才創(chuàng)建的虛擬機(jī),并指定內(nèi)存大小為 2GB,使用 Windows 10 的 ISO 鏡像文件進(jìn)行安裝,可以使用以下命令:
qemu-system-x86_64 -m 2048 -cdrom /path/to/windows10.iso -drive file=myvm.qcow2,format=qcow2
其中,-m參數(shù)指定虛擬機(jī)的內(nèi)存大小,單位為 MB,這里設(shè)置為 2048MB,即 2GB 。-cdrom參數(shù)指定用于安裝操作系統(tǒng)的 ISO 鏡像文件的路徑,/path/to/windows10.iso需要替換為實(shí)際的 Windows 10 ISO 鏡像文件的路徑 。-drive參數(shù)用于指定虛擬機(jī)的磁盤(pán)驅(qū)動(dòng)器,file=myvm.qcow2指定使用前面創(chuàng)建的磁盤(pán)鏡像文件,format=qcow2指定磁盤(pán)鏡像的格式為 qcow2 。執(zhí)行該命令后,會(huì)彈出一個(gè)窗口,顯示虛擬機(jī)的啟動(dòng)界面,用戶可以按照提示進(jìn)行操作系統(tǒng)的安裝 。
⑶管理虛擬機(jī):在虛擬機(jī)運(yùn)行過(guò)程中,可以使用一些命令來(lái)管理虛擬機(jī) 。例如,要暫停虛擬機(jī)的運(yùn)行,可以在 Qemu 的控制臺(tái)中按下Ctrl + Alt + 2組合鍵,進(jìn)入 Qemu 的監(jiān)視器模式,然后輸入stop命令 。要恢復(fù)虛擬機(jī)的運(yùn)行,在監(jiān)視器模式下輸入cont命令即可 。如果要關(guān)閉虛擬機(jī),可以在監(jiān)視器模式下輸入system_powerdown命令 。
此外,還可以使用savevm命令來(lái)保存虛擬機(jī)的當(dāng)前狀態(tài),使用loadvm命令來(lái)加載保存的狀態(tài) 。例如,要保存虛擬機(jī)的當(dāng)前狀態(tài)為 “snapshot1”,可以在監(jiān)視器模式下輸入savevm snapshot1命令;要加載名為 “snapshot1” 的狀態(tài),可以輸入loadvm snapshot1命令 。
1.4Qemu獨(dú)特功能
全系統(tǒng)仿真:Qemu 的全系統(tǒng)仿真功能堪稱一絕,它能夠模擬完整的計(jì)算機(jī)系統(tǒng),包括 CPU、內(nèi)存、存儲(chǔ)設(shè)備、網(wǎng)絡(luò)設(shè)備等 。這意味著用戶可以在 Qemu 中運(yùn)行各種操作系統(tǒng),無(wú)論是 Windows、Linux、macOS,還是一些小眾的嵌入式操作系統(tǒng),都不在話下。例如,安全研究人員可以利用 Qemu 搭建一個(gè)包含特定操作系統(tǒng)和應(yīng)用程序的模擬環(huán)境,用于進(jìn)行漏洞挖掘和安全測(cè)試,不用擔(dān)心對(duì)真實(shí)系統(tǒng)造成損害。在開(kāi)發(fā)操作系統(tǒng)時(shí),開(kāi)發(fā)者也可以借助 Qemu 的全系統(tǒng)仿真功能,在虛擬環(huán)境中進(jìn)行開(kāi)發(fā)和調(diào)試,方便快捷。
- 動(dòng)態(tài)二進(jìn)制翻譯:這是 Qemu 的核心技術(shù)之一,動(dòng)態(tài)二進(jìn)制翻譯技術(shù)允許 Qemu 在運(yùn)行時(shí)將客戶機(jī)的指令集動(dòng)態(tài)轉(zhuǎn)換為宿主機(jī)的指令集 。通過(guò)這種方式,Qemu 能夠在不同架構(gòu)的宿主機(jī)上運(yùn)行不同架構(gòu)的客戶機(jī)操作系統(tǒng),實(shí)現(xiàn)了跨架構(gòu)的虛擬化。例如,在 x86 架構(gòu)的主機(jī)上運(yùn)行 ARM 架構(gòu)的操作系統(tǒng)時(shí),Qemu 會(huì)將 ARM 指令動(dòng)態(tài)翻譯成 x86 指令,讓程序能夠在 x86 主機(jī)上順利運(yùn)行。這種技術(shù)不僅提高了 Qemu 的兼容性,還在一定程度上提升了性能,因?yàn)樗梢愿鶕?jù)實(shí)際運(yùn)行情況對(duì)指令進(jìn)行優(yōu)化。
- 豐富的設(shè)備模擬:Qemu 提供了豐富的設(shè)備模擬功能,支持多種常見(jiàn)的硬件設(shè)備,如虛擬網(wǎng)卡、虛擬磁盤(pán)、虛擬顯卡、USB 設(shè)備等 。這些設(shè)備模擬使得虛擬機(jī)可以與外部環(huán)境進(jìn)行交互,滿足各種應(yīng)用場(chǎng)景的需求。比如,在進(jìn)行網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)和測(cè)試時(shí),用戶可以在 Qemu 虛擬機(jī)中模擬不同類(lèi)型的網(wǎng)絡(luò)設(shè)備,測(cè)試應(yīng)用程序在不同網(wǎng)絡(luò)環(huán)境下的性能和穩(wěn)定性。同時(shí),Qemu 還支持對(duì)一些特殊設(shè)備的模擬,為特定領(lǐng)域的開(kāi)發(fā)和研究提供了便利。
- 插件擴(kuò)展功能:Qemu 具備良好的插件擴(kuò)展機(jī)制,用戶可以通過(guò)編寫(xiě)插件來(lái)擴(kuò)展 Qemu 的功能 。這使得 Qemu 能夠適應(yīng)各種復(fù)雜的應(yīng)用場(chǎng)景和用戶需求。例如,一些開(kāi)發(fā)者編寫(xiě)了自定義的設(shè)備插件,用于模擬特定的硬件設(shè)備,滿足特定行業(yè)的開(kāi)發(fā)和測(cè)試需求。還有一些插件用于優(yōu)化 Qemu 的性能、增強(qiáng)安全性或者提供新的管理功能,使得 Qemu 的功能不斷豐富和完善。
二、Qemu 的工作原理
QEMU作為系統(tǒng)模擬器時(shí),會(huì)模擬出一臺(tái)能夠獨(dú)立運(yùn)行操作系統(tǒng)的虛擬機(jī)。如下圖所示,每個(gè)虛擬機(jī)對(duì)應(yīng)主機(jī)(Host)中的一個(gè)QEMU進(jìn)程,而虛擬機(jī)的vCPU對(duì)應(yīng)QEMU進(jìn)程的一個(gè)線程。
系統(tǒng)虛擬化最主要是虛擬出CPU、內(nèi)存及I/O設(shè)備。虛擬出的CPU稱之為vCPU,QEMU為了提升效率,借用KVM、XEN等虛擬化技術(shù),直接利用硬件對(duì)虛擬化的支持,在主機(jī)上安全地運(yùn)行虛擬機(jī)代碼(需要硬件支持)。虛擬機(jī)vCPU調(diào)用KVM的接口來(lái)執(zhí)行任務(wù)的流程如下:
open("/dev/kvm")
ioctl(KVM_CREATE_VM)
ioctl(KVM_CREATE_VCPU)
for (;;) {
ioctl(KVM_RUN)
switch (exit_reason) {
case KVM_EXIT_IO: /* ... */
case KVM_EXIT_HLT: /* ... */
}
}
QEMU發(fā)起ioctrl來(lái)調(diào)用KVM接口,KVM則利用硬件擴(kuò)展直接將虛擬機(jī)代碼運(yùn)行于主機(jī)之上,一旦vCPU需要操作設(shè)備寄存器,vCPU將會(huì)停止并退回到QEMU,QEMU去模擬出操作結(jié)果。
虛擬機(jī)內(nèi)存會(huì)被映射到QEMU的進(jìn)程地址空間,在啟動(dòng)時(shí)分配。在虛擬機(jī)看來(lái),QEMU所分配的主機(jī)上的虛擬地址空間為虛擬機(jī)的物理地址空間。
QEMU在主機(jī)用戶態(tài)模擬虛擬機(jī)的硬件設(shè)備,vCPU對(duì)硬件的操作結(jié)果會(huì)在用戶態(tài)進(jìn)行模擬,如虛擬機(jī)需要將數(shù)據(jù)寫(xiě)入硬盤(pán),實(shí)際結(jié)果是將數(shù)據(jù)寫(xiě)入到了主機(jī)中的一個(gè)鏡像文件中。
2.1系統(tǒng)架構(gòu)解讀
Qemu 的系統(tǒng)架構(gòu)可以分為用戶態(tài)和內(nèi)核態(tài)兩大部分,這種分層設(shè)計(jì)使得 Qemu 能夠高效地實(shí)現(xiàn)硬件模擬和虛擬化功能,各部分組件相互協(xié)作,共同為虛擬機(jī)提供完整的運(yùn)行環(huán)境。
在用戶態(tài),Qemu 包含了豐富的組件。用戶接口是用戶與 Qemu 交互的橋梁,用戶可以通過(guò)命令行、圖形界面或者 API 等方式,向 Qemu 發(fā)送各種指令,如創(chuàng)建虛擬機(jī)、啟動(dòng)虛擬機(jī)、配置虛擬機(jī)參數(shù)等 。設(shè)備模型是用戶態(tài)的重要組成部分,它負(fù)責(zé)模擬各種硬件設(shè)備的行為。Qemu 通過(guò)設(shè)備模型模擬出虛擬的 CPU、內(nèi)存、硬盤(pán)、網(wǎng)卡、顯卡等設(shè)備,使得虛擬機(jī)中的操作系統(tǒng)能夠像在真實(shí)硬件上一樣訪問(wèn)這些設(shè)備。以虛擬網(wǎng)卡為例,設(shè)備模型會(huì)模擬網(wǎng)卡的接收和發(fā)送數(shù)據(jù)的功能,當(dāng)虛擬機(jī)中的操作系統(tǒng)發(fā)送網(wǎng)絡(luò)數(shù)據(jù)包時(shí),設(shè)備模型會(huì)將這些數(shù)據(jù)包進(jìn)行處理,并通過(guò)宿主機(jī)的網(wǎng)絡(luò)接口發(fā)送出去;反之,當(dāng)宿主機(jī)接收到網(wǎng)絡(luò)數(shù)據(jù)包時(shí),設(shè)備模型會(huì)將其轉(zhuǎn)發(fā)給虛擬機(jī)中的操作系統(tǒng)。
虛擬設(shè)備驅(qū)動(dòng)程序也是用戶態(tài)的關(guān)鍵組件之一,它為虛擬機(jī)中的操作系統(tǒng)提供了訪問(wèn)虛擬設(shè)備的接口。這些驅(qū)動(dòng)程序模擬了真實(shí)設(shè)備驅(qū)動(dòng)程序的功能,使得操作系統(tǒng)能夠正常識(shí)別和使用虛擬設(shè)備。例如,虛擬顯卡的驅(qū)動(dòng)程序會(huì)模擬真實(shí)顯卡的功能,將虛擬機(jī)中的圖形數(shù)據(jù)進(jìn)行處理和渲染,然后通過(guò)宿主機(jī)的顯示設(shè)備展示出來(lái)。
在內(nèi)核態(tài),Qemu 主要包含虛擬機(jī)監(jiān)控程序(VMM)和虛擬機(jī)管理器(VM Manager) 。VMM 是 Qemu 的核心組件之一,它負(fù)責(zé)管理虛擬機(jī)的運(yùn)行狀態(tài),監(jiān)控虛擬機(jī)的指令執(zhí)行,實(shí)現(xiàn)硬件虛擬化的核心功能。VMM 通過(guò)與宿主機(jī)內(nèi)核的交互,實(shí)現(xiàn)對(duì) CPU、內(nèi)存等硬件資源的虛擬化管理。例如,在處理 CPU 虛擬化時(shí),VMM 會(huì)負(fù)責(zé)模擬目標(biāo)架構(gòu)的指令集、寄存器等關(guān)鍵組件,使得虛擬機(jī)能夠運(yùn)行不同架構(gòu)的操作系統(tǒng)。當(dāng)虛擬機(jī)執(zhí)行指令時(shí),VMM 會(huì)捕獲這些指令,并根據(jù)需要進(jìn)行處理和轉(zhuǎn)換,然后將其發(fā)送給宿主機(jī) CPU 執(zhí)行。
VM Manager 則主要負(fù)責(zé)虛擬機(jī)的創(chuàng)建、管理和調(diào)度。它根據(jù)用戶的請(qǐng)求,創(chuàng)建新的虛擬機(jī),并為其分配必要的資源,如內(nèi)存、CPU 時(shí)間片等 。同時(shí),VM Manager 還負(fù)責(zé)監(jiān)控虛擬機(jī)的運(yùn)行狀態(tài),在多個(gè)虛擬機(jī)之間進(jìn)行資源調(diào)度,確保每個(gè)虛擬機(jī)都能夠獲得合理的資源分配,從而保證整個(gè)系統(tǒng)的性能和穩(wěn)定性。當(dāng)一個(gè)虛擬機(jī)需要更多的 CPU 時(shí)間片時(shí),VM Manager 會(huì)根據(jù)預(yù)設(shè)的調(diào)度策略,調(diào)整各個(gè)虛擬機(jī)的 CPU 分配,使得系統(tǒng)資源得到合理利用。
用戶態(tài)和內(nèi)核態(tài)的組件之間通過(guò)特定的接口進(jìn)行交互,以實(shí)現(xiàn)高效的協(xié)作。例如,用戶態(tài)的設(shè)備模型通過(guò)與內(nèi)核態(tài)的 VMM 進(jìn)行交互,將虛擬機(jī)對(duì)硬件設(shè)備的訪問(wèn)請(qǐng)求傳遞給 VMM,VMM 再根據(jù)請(qǐng)求進(jìn)行相應(yīng)的處理,并將結(jié)果返回給設(shè)備模型,設(shè)備模型最后將結(jié)果返回給虛擬機(jī)中的操作系統(tǒng) 。這種交互機(jī)制確保了虛擬機(jī)能夠在 Qemu 提供的模擬環(huán)境中正常運(yùn)行,同時(shí)也保證了系統(tǒng)的性能和穩(wěn)定性。
2.2指令翻譯與虛擬化實(shí)現(xiàn)
(1)動(dòng)態(tài)二進(jìn)制翻譯技術(shù):動(dòng)態(tài)二進(jìn)制翻譯是 Qemu 實(shí)現(xiàn)虛擬化的核心技術(shù)之一,它允許 Qemu 在運(yùn)行時(shí)將客戶機(jī)的指令集動(dòng)態(tài)轉(zhuǎn)換為宿主機(jī)的指令集 。簡(jiǎn)單來(lái)說(shuō),當(dāng)虛擬機(jī)中的操作系統(tǒng)執(zhí)行指令時(shí),Qemu 會(huì)將這些指令實(shí)時(shí)翻譯成宿主機(jī)能夠理解和執(zhí)行的指令。例如,在 x86 架構(gòu)的宿主機(jī)上運(yùn)行 ARM 架構(gòu)的虛擬機(jī)時(shí),Qemu 會(huì)將 ARM 指令動(dòng)態(tài)翻譯成 x86 指令,使得 ARM 架構(gòu)的操作系統(tǒng)和應(yīng)用程序能夠在 x86 主機(jī)上順利運(yùn)行。
Qemu 使用了一種稱為 “Tiny Code Generator(TCG)” 的技術(shù)來(lái)實(shí)現(xiàn)動(dòng)態(tài)二進(jìn)制翻譯 。TCG 是一個(gè)輕量級(jí)的代碼生成器,它能夠?qū)⒖蛻魴C(jī)的指令動(dòng)態(tài)地轉(zhuǎn)換為宿主機(jī)的指令,并生成高效的機(jī)器碼。具體過(guò)程如下:首先,Qemu 從虛擬機(jī)中讀取客戶機(jī)的指令,然后將這些指令翻譯成 TCG 中間表示形式(IR) 。TCG 中間表示是一種抽象的指令表示,它不依賴于具體的硬件架構(gòu),具有較高的通用性。接下來(lái),TCG 會(huì)根據(jù)宿主機(jī)的架構(gòu),將中間表示進(jìn)一步翻譯成宿主機(jī)的目標(biāo)指令 。在翻譯過(guò)程中,TCG 會(huì)對(duì)指令進(jìn)行優(yōu)化,以提高執(zhí)行效率。例如,它會(huì)合并一些可以合并的指令,減少指令的執(zhí)行次數(shù);還會(huì)根據(jù)宿主機(jī)的硬件特性,選擇最合適的指令序列來(lái)實(shí)現(xiàn)相同的功能。通過(guò)這種動(dòng)態(tài)二進(jìn)制翻譯技術(shù),Qemu 能夠在不同架構(gòu)的宿主機(jī)上運(yùn)行各種不同架構(gòu)的客戶機(jī)操作系統(tǒng),大大提高了虛擬化的靈活性和兼容性。
(2)中斷與模擬設(shè)備操作實(shí)現(xiàn)虛擬化:中斷是計(jì)算機(jī)系統(tǒng)中一種重要的機(jī)制,用于處理異步事件。在 Qemu 的虛擬化環(huán)境中,中斷的模擬和處理對(duì)于實(shí)現(xiàn)完整的虛擬化至關(guān)重要 。當(dāng)虛擬機(jī)中的設(shè)備產(chǎn)生中斷請(qǐng)求時(shí),Qemu 需要準(zhǔn)確地模擬這個(gè)中斷過(guò)程,將中斷信號(hào)傳遞給虛擬機(jī)中的操作系統(tǒng),并確保操作系統(tǒng)能夠正確地響應(yīng)和處理這個(gè)中斷。
以虛擬網(wǎng)卡為例,當(dāng)宿主機(jī)接收到網(wǎng)絡(luò)數(shù)據(jù)包時(shí),虛擬網(wǎng)卡設(shè)備模型會(huì)產(chǎn)生一個(gè)中斷請(qǐng)求,通知虛擬機(jī)中的操作系統(tǒng)有新的網(wǎng)絡(luò)數(shù)據(jù)到達(dá) 。Qemu 會(huì)捕獲這個(gè)中斷請(qǐng)求,并將其轉(zhuǎn)換為虛擬機(jī)能夠識(shí)別的中斷信號(hào),然后傳遞給虛擬機(jī)中的操作系統(tǒng)。操作系統(tǒng)接收到中斷信號(hào)后,會(huì)調(diào)用相應(yīng)的中斷處理程序,從虛擬網(wǎng)卡中讀取網(wǎng)絡(luò)數(shù)據(jù)包,并進(jìn)行后續(xù)的處理。在這個(gè)過(guò)程中,Qemu 需要模擬中斷控制器的行為,確保中斷信號(hào)的正確傳遞和處理。
同時(shí),Qemu 對(duì)設(shè)備的模擬操作也是實(shí)現(xiàn)虛擬化的關(guān)鍵。Qemu 通過(guò)軟件模擬各種硬件設(shè)備的功能和行為,使得虛擬機(jī)中的操作系統(tǒng)能夠像操作真實(shí)硬件設(shè)備一樣操作這些虛擬設(shè)備 。例如,在模擬硬盤(pán)設(shè)備時(shí),Qemu 會(huì)模擬硬盤(pán)的讀寫(xiě)操作。當(dāng)虛擬機(jī)中的操作系統(tǒng)向虛擬硬盤(pán)寫(xiě)入數(shù)據(jù)時(shí),Qemu 會(huì)將數(shù)據(jù)存儲(chǔ)在宿主機(jī)的文件系統(tǒng)中,以模擬硬盤(pán)的存儲(chǔ)功能;當(dāng)操作系統(tǒng)從虛擬硬盤(pán)讀取數(shù)據(jù)時(shí),Qemu 會(huì)從宿主機(jī)的文件系統(tǒng)中讀取相應(yīng)的數(shù)據(jù),并返回給操作系統(tǒng)。通過(guò)這種方式,Qemu 實(shí)現(xiàn)了對(duì)硬件設(shè)備的完整模擬,為虛擬機(jī)提供了一個(gè)與真實(shí)硬件環(huán)境相似的運(yùn)行環(huán)境,使得各種操作系統(tǒng)和應(yīng)用程序能夠在虛擬機(jī)中正常運(yùn)行,實(shí)現(xiàn)了高效的硬件虛擬化。
2.3創(chuàng)建及使用虛擬機(jī)
使用qemu-img創(chuàng)建虛擬機(jī)鏡像,虛擬機(jī)鏡像用來(lái)模擬虛擬機(jī)的硬盤(pán),在啟動(dòng)虛擬機(jī)之前需要?jiǎng)?chuàng)建鏡像文件。
qemu-img create -f qcow2 test-vm-1.qcow2 10G
-f 選項(xiàng)用于指定鏡像的格式,qcow2 格式是 Qemu 最常用的鏡像格式,采用來(lái)寫(xiě)時(shí)復(fù)制技術(shù)來(lái)優(yōu)化性能。test-vm-1.qcow2 是鏡像文件的名字,10G是鏡像文件大小。鏡像文件創(chuàng)建完成后,可使用 qemu-system-x86 來(lái)啟動(dòng)x86 架構(gòu)的虛擬機(jī):
使用 qemu-system-x86 來(lái)啟動(dòng) x86 架構(gòu)的虛擬機(jī)
qemu-system-x86_64 test-vm-1.qcow2
因?yàn)?test-vm-1.qcow2 中并未給虛擬機(jī)安裝操作系統(tǒng),所以會(huì)提示 “No bootable device”,無(wú)可啟動(dòng)設(shè)備。
啟動(dòng) VM 安裝操作系統(tǒng)鏡像
qemu-system-x86_64 -m 2048 -enable-kvm test-vm-1.qcow2 -cdrom ./Centos-Desktop-x86_64-20-1.iso
-m 指定虛擬機(jī)內(nèi)存大小,默認(rèn)單位是 MB, -enable-kvm 使用 KVM 進(jìn)行加速,-cdrom 添加 fedora 的安裝鏡像??稍趶棾龅拇翱谥胁僮魈摂M機(jī),安裝操作系統(tǒng),安裝完成后重起虛擬機(jī)便會(huì)從硬盤(pán) ( test-vm-1.qcow2 ) 啟動(dòng)。之后再啟動(dòng)虛擬機(jī)只需要執(zhí)行:
qemu-system-x86_64 -m 2048 -enable-kvm test-vm-1.qcow2
qemu-img 支持非常多種的文件格式,可以通過(guò) qemu-img -h 查看,其中 raw 和 qcow2 是比較常用的兩種,raw 是 qemu-img 命令默認(rèn)的,qcow2 是 qemu 目前推薦的鏡像格式,是功能最多的格式。
三、Qemu應(yīng)用場(chǎng)景
3.1開(kāi)發(fā)與測(cè)試領(lǐng)域
在軟件開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)人員常常需要在不同的操作系統(tǒng)和硬件平臺(tái)上對(duì)軟件進(jìn)行測(cè)試,以確保軟件的兼容性和穩(wěn)定性 。Qemu 提供了一個(gè)理想的測(cè)試環(huán)境,它可以模擬多種硬件架構(gòu)和操作系統(tǒng),讓開(kāi)發(fā)人員在一臺(tái)物理計(jì)算機(jī)上就能完成對(duì)軟件在不同環(huán)境下的測(cè)試工作。例如,開(kāi)發(fā)一款跨平臺(tái)的應(yīng)用程序時(shí),開(kāi)發(fā)人員可以利用 Qemu 創(chuàng)建 Windows、Linux、macOS 等多種操作系統(tǒng)的虛擬機(jī),在這些虛擬機(jī)中分別運(yùn)行應(yīng)用程序,測(cè)試其在不同系統(tǒng)下的功能完整性、界面顯示、性能表現(xiàn)等 。這樣可以提前發(fā)現(xiàn)并解決軟件在不同平臺(tái)上可能出現(xiàn)的兼容性問(wèn)題,大大提高軟件的質(zhì)量和可靠性。
對(duì)于硬件開(kāi)發(fā),Qemu 同樣發(fā)揮著重要作用。在硬件設(shè)計(jì)階段,工程師可以使用 Qemu 模擬目標(biāo)硬件平臺(tái),進(jìn)行硬件相關(guān)軟件的開(kāi)發(fā)和調(diào)試 。比如,開(kāi)發(fā)一款基于 ARM 架構(gòu)的嵌入式系統(tǒng)時(shí),在實(shí)際硬件還未生產(chǎn)出來(lái)之前,工程師就可以利用 Qemu 模擬 ARM 硬件環(huán)境,編寫(xiě)和調(diào)試驅(qū)動(dòng)程序、操作系統(tǒng)內(nèi)核等軟件部分。通過(guò)在 Qemu 模擬環(huán)境中進(jìn)行充分的測(cè)試和優(yōu)化,可以減少硬件開(kāi)發(fā)過(guò)程中的錯(cuò)誤和風(fēng)險(xiǎn),縮短硬件開(kāi)發(fā)周期,降低開(kāi)發(fā)成本 。而且,Qemu 支持對(duì)硬件設(shè)備的詳細(xì)模擬,工程師可以模擬各種硬件故障和異常情況,測(cè)試軟件在這些情況下的應(yīng)對(duì)能力,提高硬件系統(tǒng)的穩(wěn)定性和可靠性。
3.2云計(jì)算與數(shù)據(jù)中心
在云計(jì)算和數(shù)據(jù)中心領(lǐng)域,Qemu 是實(shí)現(xiàn)資源虛擬化的關(guān)鍵技術(shù)之一 。它與 KVM(Kernel-based Virtual Machine)相結(jié)合,為云計(jì)算提供了強(qiáng)大的支持。KVM 是 Linux 內(nèi)核中的一個(gè)模塊,它利用硬件虛擬化擴(kuò)展(如 Intel VT 或 AMD-V)來(lái)實(shí)現(xiàn)高效的虛擬化 。
Qemu 則作為 KVM 的用戶空間工具,負(fù)責(zé)模擬硬件設(shè)備,為虛擬機(jī)提供完整的運(yùn)行環(huán)境。通過(guò)這種組合,云計(jì)算提供商可以在一臺(tái)物理服務(wù)器上創(chuàng)建多個(gè)虛擬機(jī),將服務(wù)器的計(jì)算、存儲(chǔ)和網(wǎng)絡(luò)資源進(jìn)行虛擬化分割,為不同的用戶提供獨(dú)立的虛擬機(jī)服務(wù) 。
這種虛擬化技術(shù)在云計(jì)算和數(shù)據(jù)中心中有諸多優(yōu)勢(shì)。首先,它提高了服務(wù)器的資源利用率。傳統(tǒng)的數(shù)據(jù)中心中,服務(wù)器的資源往往不能得到充分利用,很多服務(wù)器在大部分時(shí)間內(nèi)處于低負(fù)載運(yùn)行狀態(tài) 。通過(guò)虛擬化技術(shù),多個(gè)虛擬機(jī)可以共享一臺(tái)物理服務(wù)器的資源,根據(jù)實(shí)際需求動(dòng)態(tài)分配資源,大大提高了服務(wù)器的利用率,降低了硬件成本和能源消耗 。
其次,虛擬化技術(shù)增強(qiáng)了系統(tǒng)的靈活性和可擴(kuò)展性。云計(jì)算提供商可以根據(jù)用戶的需求,快速創(chuàng)建、刪除或調(diào)整虛擬機(jī)的配置,實(shí)現(xiàn)資源的動(dòng)態(tài)分配和回收 。用戶也可以根據(jù)自己的業(yè)務(wù)需求,靈活選擇虛擬機(jī)的規(guī)格和配置,無(wú)需擔(dān)心硬件資源的限制。此外,Qemu和KVM的結(jié)合還提供了良好的隔離性和安全性,每個(gè)虛擬機(jī)都運(yùn)行在獨(dú)立的隔離環(huán)境中,相互之間不會(huì)干擾,保證了用戶數(shù)據(jù)的安全和隱私 。
3.3教育與科研用途
在教育領(lǐng)域,Qemu 為學(xué)生和教師提供了一個(gè)便捷的實(shí)驗(yàn)環(huán)境 。在計(jì)算機(jī)相關(guān)課程的教學(xué)中,學(xué)生常常需要實(shí)踐操作不同的操作系統(tǒng)和硬件環(huán)境,但由于實(shí)際硬件設(shè)備的限制,很難為每個(gè)學(xué)生提供多樣化的實(shí)驗(yàn)環(huán)境 。Qemu 的出現(xiàn)解決了這個(gè)問(wèn)題,教師可以利用 Qemu 創(chuàng)建多個(gè)虛擬機(jī),每個(gè)虛擬機(jī)運(yùn)行不同的操作系統(tǒng)和實(shí)驗(yàn)軟件,學(xué)生可以在虛擬機(jī)中進(jìn)行各種實(shí)驗(yàn)操作,如操作系統(tǒng)安裝、配置,網(wǎng)絡(luò)實(shí)驗(yàn),軟件開(kāi)發(fā)等 。這樣不僅提高了教學(xué)效果,還能讓學(xué)生在實(shí)踐中更好地理解計(jì)算機(jī)系統(tǒng)的原理和機(jī)制。
在科研方面,Qemu 也有著廣泛的應(yīng)用 ??蒲腥藛T在進(jìn)行計(jì)算機(jī)體系結(jié)構(gòu)、操作系統(tǒng)、網(wǎng)絡(luò)協(xié)議等領(lǐng)域的研究時(shí),常常需要搭建復(fù)雜的實(shí)驗(yàn)環(huán)境 。Qemu 可以模擬各種硬件平臺(tái)和操作系統(tǒng),為科研人員提供了一個(gè)靈活、可定制的實(shí)驗(yàn)平臺(tái) 。例如,在研究新型的計(jì)算機(jī)體系結(jié)構(gòu)時(shí),科研人員可以利用 Qemu 模擬新的處理器架構(gòu)和硬件設(shè)備,驗(yàn)證設(shè)計(jì)的可行性和性能優(yōu)勢(shì) 。
在研究操作系統(tǒng)的性能優(yōu)化和安全機(jī)制時(shí),科研人員可以在 Qemu 虛擬機(jī)中運(yùn)行不同版本的操作系統(tǒng),進(jìn)行各種性能測(cè)試和安全實(shí)驗(yàn) 。Qemu 還支持對(duì)網(wǎng)絡(luò)設(shè)備和網(wǎng)絡(luò)協(xié)議的模擬,方便科研人員進(jìn)行網(wǎng)絡(luò)相關(guān)的研究和實(shí)驗(yàn),推動(dòng)科研工作的順利開(kāi)展。
四、Qemu源碼結(jié)構(gòu)
Qemu軟件虛擬化實(shí)現(xiàn)的思路是采用二進(jìn)制指令翻譯技術(shù),主要是提取 guest 代碼,然后將其翻譯成 TCG 中間代碼,最后再將中間代碼翻譯成 host 指定架構(gòu)的代碼,如 x86 體系就翻譯成其支持的代碼形式,ARM 架構(gòu)同理。
圖片
所以,從宏觀上看,源碼結(jié)構(gòu)主要包含以下幾個(gè)部分:
- /vl.c:最主要的模擬循環(huán),虛擬機(jī)環(huán)境初始化,和 CPU 的執(zhí)行。
- /target-arch/translate.c:將 guest 代碼翻譯成不同架構(gòu)的 TCG 操作碼。
- /tcg/tcg.c:主要的 TCG 代碼。
- /tcg/arch/tcg-target.c:將 TCG 代碼轉(zhuǎn)化生成主機(jī)代碼。
- /cpu-exec.c:主要尋找下一個(gè)二進(jìn)制翻譯代碼塊,如果沒(méi)有找到就請(qǐng)求得到下一個(gè)代碼塊,并且操作生成的代碼塊。
其中,涉及的主要幾個(gè)函數(shù)如下:
圖片
知道了這個(gè)總體的代碼結(jié)構(gòu),再去具體了解每一個(gè)模塊可能會(huì)相對(duì)容易一點(diǎn)。
(1)開(kāi)始執(zhí)行
主要比較重要的c文件有:/vl.c,/cpus.c, /exec-all.c, /exec.c, /cpu-exec.c。
QEMU的main函數(shù)定義在/vl.c中,它也是執(zhí)行的起點(diǎn),這個(gè)函數(shù)的功能主要是建立一個(gè)虛擬的硬件環(huán)境。它通過(guò)參數(shù)的解析,將初始化內(nèi)存,需要的模擬的設(shè)備初始化,CPU參數(shù),初始化KVM等等。接著程序就跳轉(zhuǎn)到其他的執(zhí)行分支文件如:/cpus.c, /exec-all.c, /exec.c, /cpu-exec.c。
(2)硬件模擬
所有的硬件設(shè)備都在/hw/ 目錄下面,所有的設(shè)備都有獨(dú)自的文件,包括總線,串口,網(wǎng)卡,鼠標(biāo)等等。它們通過(guò)設(shè)備模塊串在一起,在vl.c中的machine _init中初始化。這里就不講每種設(shè)備是怎么實(shí)現(xiàn)的了。
(3)目標(biāo)機(jī)器
現(xiàn)在QEMU模擬的CPU架構(gòu)有:Alpha, ARM, Cris, i386, M68K, PPC, Sparc, Mips, MicroBlaze, S390X and SH4。
我們?cè)赒EMU中使用./configure 可以配置運(yùn)行的架構(gòu),這個(gè)腳本會(huì)自動(dòng)讀取本機(jī)真實(shí)機(jī)器的CPU架構(gòu),并且編譯的時(shí)候就編譯對(duì)應(yīng)架構(gòu)的代碼。對(duì)于不同的QEMU做的事情都不同,所以不同架 構(gòu)下的代碼在不同的目錄下面。/target-arch/目錄就對(duì)應(yīng)了相應(yīng)架構(gòu)的代碼,如/target-i386/就對(duì)應(yīng)了x86系列的代碼部分。雖然 不同架構(gòu)做法不同,但是都是為了實(shí)現(xiàn)將對(duì)應(yīng)客戶機(jī)CPU架構(gòu)的TBs轉(zhuǎn)化成TCG的中間代碼。這個(gè)就是TCG的前半部分。
(4)主機(jī)
這個(gè)部分就是使用TCG代碼生成主機(jī)的代碼,這部分代碼在/tcg/里面,在這個(gè)目錄里面也對(duì)應(yīng)了不同的架構(gòu),分別在不同的子目錄里面,如i386就在/tcg/i386中。整個(gè)生成主機(jī)代碼的過(guò)程也可以教TCG的后半部分。
(5)文件總結(jié)
/vl.c: 最主要的模擬循環(huán),虛擬機(jī)機(jī)器環(huán)境初始化,和CPU的執(zhí)行。
/target-arch/translate.c 將客戶機(jī)代碼轉(zhuǎn)化成不同架構(gòu)的TCG操作碼。
/tcg/tcg.c 主要的TCG代碼。
/tcg/arch/tcg-target.c 將TCG代碼轉(zhuǎn)化生成主機(jī)代碼
/cpu-exec.c 其中的cpu-exec()函數(shù)主要尋找下一個(gè)TB(翻譯代碼塊),如果沒(méi)找到就請(qǐng)求得到下一個(gè)TB,并且操作生成的代碼塊。
4.1TCG動(dòng)態(tài)翻譯
QEMU在 0.9.1版本之前使用DynGen翻譯c代碼.當(dāng)我們需要的時(shí)候TCG會(huì)動(dòng)態(tài)的轉(zhuǎn)變代碼,這個(gè)想法的目的是用更多的時(shí)間去執(zhí)行我們生成的代碼。當(dāng)新的代 碼從TB中生成以后, 將會(huì)被保存到一個(gè)cache中,因?yàn)楹芏嘞嗤腡B會(huì)被反復(fù)的進(jìn)行操作,所以這樣類(lèi)似于內(nèi)存的cache,能夠提高使用效率。而 cache的刷新使用LRU算法。
圖片
編譯器在執(zhí)行器會(huì)從源代碼中產(chǎn)生目標(biāo)代碼,像GCC這種編譯器,它為了產(chǎn)生像函數(shù)調(diào)用目標(biāo)代碼會(huì)產(chǎn)生一些特殊的匯編目標(biāo)代碼,他們能夠讓編譯器需要知道在調(diào)用函數(shù)。需要什么,以及函數(shù)調(diào)用以后需要返回什么,這些特殊的匯編代碼產(chǎn)生過(guò)程就叫做函數(shù)的Prologue和Epilogue,這里就叫前端和后段吧。我在其他文章中也分析過(guò)匯編調(diào)用函數(shù)的過(guò)程,至于匯編里面函數(shù)調(diào)用過(guò)程中寄存器是如何變化的,在本文中就不再描述了。
函數(shù)的后端會(huì)恢復(fù)前端的狀態(tài),主要做下面2點(diǎn):
- 恢復(fù)堆棧的指針,包括棧頂和基地址。
- 修改cs和ip,程序回到之前的前端記錄點(diǎn)。
TCG就如編譯器一樣可以產(chǎn)生目標(biāo)代碼,代碼會(huì)保存在緩沖區(qū)中,當(dāng)進(jìn)入前端和后端的時(shí)候就會(huì)將TCG生成的緩沖代碼插入到目標(biāo)代碼中。
接下來(lái)我們就來(lái)看下如何翻譯代碼的:
①客戶機(jī)代碼
圖片
②TCG中間代碼
圖片
③主機(jī)代碼
圖片
4.2TB鏈
在QEMU中,從代碼cache到靜態(tài)代碼再回到代碼cache,這個(gè)過(guò)程比較耗時(shí),所以在QEMU中涉及了一個(gè)TB鏈將所有TB連在一起,可以讓一個(gè)TB執(zhí)行完以后直接跳到下一個(gè)TB,而不用每次都返回到靜態(tài)代碼部分。具體過(guò)程如下圖:
圖片
4.3TCG代碼分析
接下來(lái)來(lái)看看QEMU代碼中中到底怎么來(lái)執(zhí)行這個(gè)TCG的,看看它是如何生成主機(jī)代碼的。
main_loop(...){/vl.c} :
函數(shù)main_loop 初始化qemu_main_loop_start()然后進(jìn)入無(wú)限循環(huán)cpu_exec_all() , 這個(gè)是QEMU的一個(gè)主要循環(huán),在里面會(huì)不斷的判斷一些條件,如虛擬機(jī)的關(guān)機(jī)斷電之類(lèi)的。
qemu_main_loop_start(...){/cpus.c} :
函數(shù)設(shè)置系統(tǒng)變量 qemu_system_ready = 1并且重啟所有的線程并且等待一個(gè)條件變量。
cpu_exec_all(...){/cpus.c} :
它是cpu循環(huán),QEMU能夠啟動(dòng)256個(gè)cpu核,但是這些核將會(huì)分時(shí)運(yùn)行,然后執(zhí)行qemu_cpu_exec() 。
struct CPUState{/target-xyz/cpu.h} :
它是CPU狀態(tài)結(jié)構(gòu)體,關(guān)于cpu的各種狀態(tài),不同架構(gòu)下面還有不同。cpu_exec(...){/cpu-exec.c}:
這個(gè)函數(shù)是主要的執(zhí)行循環(huán),這里第一次翻譯之前說(shuō)道德TB,TB被初始化為(TranslationBlock *tb) ,然后不停的執(zhí)行異常處理。其中嵌套了兩個(gè)無(wú)限循環(huán) find tb_find_fast() 和tcg_qemu_tb_exec();cantb_find_fast()為客戶機(jī)初始化查詢下一個(gè)TB,并且生成主機(jī)代碼。tcg_qemu_tb_exec()執(zhí)行生成的主機(jī)代碼
struct TranslationBlock {/exec-all.h}:
結(jié)構(gòu)體TranslationBlock包含下面的成員:PC, CS_BASE, Flags (表明TB), tc_ptr (指向這個(gè)TB翻譯代碼的指針), tb_next_offset[2], tb_jmp_offset[2] (接下去的Tb), *jmp_next[2], *jmp_first (之前的TB).tb_find_fast(...){/cpu-exec.c} :
函數(shù)通過(guò)調(diào)用獲得程序指針計(jì)數(shù)器,然后傳到一個(gè)哈希函數(shù)從 tb_jmp_cache[] (一個(gè)哈希表)得到TB的所以,所以使用tb_jmp_cache可以找到下一個(gè)TB。如果沒(méi)有找到下一個(gè)TB,則使用tb_find_slow。
tb_find_slow(...){/cpu-exec.c}:
這個(gè)是在快速查找失敗以后試圖去訪問(wèn)物理內(nèi)存,尋找TB。
tb_gen_code(...){/exec.c}:
開(kāi)始分配一個(gè)新的TB,TB的PC是剛剛從CPUstate里面通過(guò)using get_page_addr_code()找到的phys_pc = get_page_addr_code(env, pc);tb = tb_alloc(pc);ph當(dāng)調(diào)用cpu_gen_code() 以后,接著會(huì)調(diào)用tb_link_page(),它將增加一個(gè)新的TB,并且指向它的物理頁(yè)表。
cpu_gen_code(...){translate-all.c}:
函數(shù)初始化真正的代碼生成,在這個(gè)函數(shù)里面有下面的函數(shù)調(diào)用:
gen_intermediate_code(){
/target-arch/translate.c}->gen_intermediate_code_internal(){
/target-arch/translate.c }->disas_insn(){/target-arch/translate.c}
disas_insn(){/target-arch/translate.c}:
函數(shù)disas_insn() 真正的實(shí)現(xiàn)將客戶機(jī)代碼翻譯成TCG代碼,它通過(guò)一長(zhǎng)串的switch case,將不同的指令做不同的翻譯,最后調(diào)用tcg_gen_code。tcg_gen_code(...){/tcg/tcg.c}:
這個(gè)函數(shù)將TCG的代碼轉(zhuǎn)化成主機(jī)代碼,這個(gè)就不細(xì)細(xì)說(shuō)明了,和前面類(lèi)似。#define tcg_qemu_tb_exec(...){/tcg/tcg.g}:通過(guò)上面的步驟,當(dāng)TB生成以后就通過(guò)這個(gè)函數(shù)進(jìn)行執(zhí)行
next_tb = tcg_qemu_tb_exec(tc_ptr) :
extern uint8_t code_gen_prologue[];
#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM(*)(void *)) code_gen_prologue)(tb_ptr)
通過(guò)上面的步驟我們就解析了QEMU是如何將客戶機(jī)代碼翻譯成主機(jī)代碼的,了解了TCG的工作原理。接下來(lái)看看QEMU與KVM是怎么聯(lián)系的。
4.4IOCTL使用流程
在QEMU-KVM中,用戶空間的QEMU是通過(guò)IOCTL與內(nèi)核空間的KVM模塊進(jìn)行通訊的。
(1)創(chuàng)建KVM
在/vl.c中通過(guò)kvm_init()將會(huì)創(chuàng)建各種KVM的結(jié)構(gòu)體變量,并且通過(guò)IOCTL與已經(jīng)初始化好的KVM模塊進(jìn)行通訊,創(chuàng)建虛擬機(jī)。然后創(chuàng)建VCPU,等等。
(2)KVM_RUN
這個(gè)IOCTL是使用最頻繁的,整個(gè)KVM運(yùn)行就不停在執(zhí)行這個(gè)IOCTL,當(dāng)KVM需要QEMU處理一些指令和IO等等的時(shí)候就會(huì)退出通過(guò)這個(gè)IOCTL退回到QEMU進(jìn)行處理,不然就會(huì)一直在KVM中執(zhí)行。
它的初始化過(guò)程:
vl.c中調(diào)用machine->init初始化硬件設(shè)備接著調(diào)用pc_init_pci,然后再調(diào)用pc_init1;接著通過(guò)下面的調(diào)用初始化KVM的主循環(huán),以及CPU循環(huán)。在CPU循環(huán)的過(guò)程中不斷的執(zhí)行KVM_RUN與KVM進(jìn)行交互。
pc_init1->pc_cpus_init->pc_new_cpu->cpu_x86_init->qemu_init_vcpu->kvm_init_vcpu->ap_main_loop->kvm_main_loop_cpu->kvm_cpu_exec->kvm_run
(3)KVM_IRQ_LINE
這個(gè)IOCTL和KVM_RUN是不同步的,它也是個(gè)頻率非常高的調(diào)用,它就是一般中斷設(shè)備的中斷注入入口。當(dāng)設(shè)備有中斷就通過(guò)這個(gè)IOCTL最終 調(diào)用KVM里面的kvm_set_irq將中斷注入到虛擬的中斷控制器。在kvm中會(huì)進(jìn)一步判斷屬于什么中斷類(lèi)型,然后在合適的時(shí)機(jī)寫(xiě)入vmcs。當(dāng)然在 KVM_RUN中會(huì)不斷的同步虛擬中斷控制器,來(lái)獲取需要注入的中斷,這些中斷包括QEMU和KVM本身的,并在重新進(jìn)入客戶機(jī)之前注入中斷。
五、Qemu中內(nèi)存管理
5.1相關(guān)配置參數(shù)
QEMU的命令行中有參數(shù):
-m [size=]megs[,slots=n,maxmem=size]
用于指定客戶機(jī)初始運(yùn)行時(shí)的內(nèi)存大小以及客戶機(jī)最大內(nèi)存大小,以及內(nèi)存芯片槽的數(shù)量(DIMM)。
之所以QEMU可以指定最大內(nèi)存、槽等參數(shù),是因?yàn)镼EMU可以模擬DIMM的熱插拔,客戶機(jī)操作系統(tǒng)可以和在真實(shí)的系統(tǒng)上一樣,檢測(cè)新內(nèi)存被插入或者拔出。也就是說(shuō),內(nèi)存熱插拔的粒度是DIMM槽(或者說(shuō)DIMM集合),而不是最小的byte。
與內(nèi)存相關(guān)的數(shù)據(jù)結(jié)構(gòu):
圖片
PCDIMMDevice和HostMemoryBackend對(duì)象都是在QEMU中用戶可見(jiàn)的客戶機(jī)內(nèi)存。它們能通過(guò)QEMU命令行或者QMP監(jiān)控器接口來(lái)管理。
PCDIMMDevice數(shù)據(jù)結(jié)構(gòu)是使用QEMU中的面向?qū)ο缶幊棠P蚎OM定義的,對(duì)應(yīng)的對(duì)象和類(lèi)的數(shù)據(jù)結(jié)構(gòu)如下。通過(guò)在QEMU進(jìn)程中創(chuàng)建一個(gè)新的PCDIMMDevice對(duì)象,就可以實(shí)現(xiàn)內(nèi)存的熱插拔。
值得注意的是,客戶機(jī)啟動(dòng)時(shí)的初始化內(nèi)存,可能不會(huì)被模擬成PCDIMMDevice設(shè)備,也就是說(shuō),這部分初始化內(nèi)存不能進(jìn)行熱插拔。PCDIMMDevice的定義在include/hw/mem/pc-dimm.h中。
typedef struct PCDIMMDevice {
/* private */
DeviceState parent_obj;
/* public */
uint64_t addr;
uint32_t node; //numa node
int32_t slot; //slot編號(hào)
HostMemoryBackend *hostmem;
} PCDIMMDevice;
typedef struct PCDIMMDeviceClass {
/* private */
DeviceClass parent_class;
/* public */
MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm);
} PCDIMMDeviceClass;
每個(gè)PCDIMMDevice對(duì)象都與 HostMemoryBackend對(duì)象相關(guān)聯(lián)。HostMemoryBackend也是使用QEMU中的面向?qū)ο缶幊棠P蚎OM定義的。HostMemoryBackend定義在include/sysemu/hostmem.h中。HostMemoryBackend對(duì)象包含了客戶機(jī)內(nèi)存對(duì)應(yīng)的真正的主機(jī)內(nèi)存,這些內(nèi)存可以是匿名映射的內(nèi)存,也可以是文件映射內(nèi)存。文件映射的客戶機(jī)內(nèi)存允許Linux在物理主機(jī)上透明大頁(yè)機(jī)制的使用(hugetlbfs),并且能夠共享內(nèi)存,從而使其他進(jìn)程可以訪問(wèn)客戶機(jī)內(nèi)存。
struct HostMemoryBackend {
/* private */
Object parent;
/* protected */
uint64_t size;
bool merge, dump;
bool prealloc, force_prealloc;
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
HostMemPolicy policy;
MemoryRegion mr;
};
struct HostMemoryBackendClass {
ObjectClass parent_class;
void (*alloc)(HostMemoryBackend *backend, Error **errp);
};
HostMemoryBackend對(duì)象中的內(nèi)存被實(shí)際映射到通過(guò)qemu_ram_alloc()函數(shù)(代碼定義在exec.c中)RAMBlock數(shù)據(jù)結(jié)構(gòu)中。每個(gè)RAMBlock都有一個(gè)指針指向被映射內(nèi)存的起始位置,同時(shí)包含一個(gè)ram_addr_t的位移變量。ram_addr_t位于全局的命名空間中,因此RAMBlock能夠通過(guò)offset來(lái)查找。
RAMBlock定義在include/exec/ram_addr.h中。RAMBlock受RCU機(jī)制保護(hù),所謂RCU,即Read-COPY-Update。
typedef uint64_t ram_addr_t;
struct RAMBlock {
struct rcu_head rcu; //該數(shù)據(jù)結(jié)構(gòu)受rcu機(jī)制保護(hù)
struct MemoryRegion *mr;
uint8_t *host; //RAMBlock的內(nèi)存起始位置
ram_addr_t offset; //在所有的RAMBlock中offset
ram_addr_t used_length; //已使用長(zhǎng)度
ram_addr_t max_length; //最大分配內(nèi)存
void (*resized)(const char*, uint64_t length, void *host);
uint32_t flags;
/* Protected by iothread lock. */
char idstr[256]; //RAMBlock的ID
/* RCU-enabled, writes protected by the ramlist lock */
QLIST_ENTRY(RAMBlock) next;
int fd; //映射文件的描述符
};
所有的RAMBlock保存在全局的RAMBlock的鏈表中,名為RAMList,它有專(zhuān)門(mén)的數(shù)據(jù)結(jié)構(gòu)定義。RAMList數(shù)據(jù)結(jié)構(gòu)定義在include/exec/ram_addr.h中,而全局的ram_list變量則定義在exec.c中。因此這個(gè)鏈表保存了客戶機(jī)的內(nèi)存對(duì)應(yīng)的所有的物理機(jī)的實(shí)際內(nèi)存信息。
5.2跟蹤臟頁(yè)
當(dāng)客戶機(jī)CPU或者DMA將數(shù)據(jù)保存到客戶機(jī)內(nèi)存時(shí),需要通知下列一些用戶:
- 熱遷移特性依賴于跟蹤臟頁(yè),因此他們能夠在被改變之后重新傳輸。
- 圖形卡模擬依賴于跟蹤臟的視頻內(nèi)存,用于重畫(huà)某些界面。
所有的CPU架構(gòu)都有內(nèi)存地址空間、有些CPU架構(gòu)又有一個(gè)IO地址空間。它們?cè)赒EMU中被表示為AddressSpace數(shù)據(jù)結(jié)構(gòu),它定義在include/exec/memory.h中。而每個(gè)地址空間都包含一個(gè)MemoryRegion的樹(shù)狀結(jié)構(gòu),所謂樹(shù)狀結(jié)構(gòu),指的是每個(gè)MemoryRegion的內(nèi)部可以含有MemoryRegion,這樣的包含所形成的樹(shù)狀結(jié)構(gòu)。
MemoryRegion是聯(lián)系客戶機(jī)內(nèi)存和包含這一部分內(nèi)存的RAMBlock。每個(gè)MemoryRegion都包含一個(gè)在RAMBlock中ram_addr_t類(lèi)型的offset,每個(gè)RAMBlock也有一個(gè)MemoryRegion的指針。
MemoryRegion不僅可以表示RAM,也可以表示I/O映射內(nèi)存,在訪問(wèn)時(shí)可以調(diào)用read/write回調(diào)函數(shù)。這也是硬件從客戶機(jī)CPU注冊(cè)的訪問(wèn)被分派到相應(yīng)的模擬設(shè)備的方法。
struct AddressSpace {
/* All fields are private. */
struct rcu_head rcu;
char *name;
MemoryRegion *root;
/* Accessed via RCU. */
struct FlatView *current_map; //AddressSpace的一張平面視圖,它是AddressSpace所有正在使用的MemoryRegion的集合,這是從CPU的視角來(lái)看到的。
int ioeventfd_nb;
struct MemoryRegionIoeventfd *ioeventfds;
struct AddressSpaceDispatch *dispatch;
struct AddressSpaceDispatch *next_dispatch;
MemoryListener dispatch_listener;
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
};
struct MemoryRegion {
Object parent_obj;
/* All fields are private - violators will be prosecuted */
const MemoryRegionOps *ops; //與MemoryRegion相關(guān)的操作
const MemoryRegionIOMMUOps *iommu_ops;
void *opaque;
MemoryRegion *container;
Int128 size;
hwaddr addr; //在AddressSpace中的地址
void (*destructor)(MemoryRegion *mr);
ram_addr_t ram_addr; //MemoryRegion的起始地址
uint64_t align; //big-endian or little-endian
bool subpage;
bool terminates;
bool romd_mode;
bool ram;
bool skip_dump;
bool readonly; /* For RAM regions */
bool enabled; //如果為true,表示已經(jīng)通知kvm使用這段內(nèi)存
bool rom_device; //是否是只讀內(nèi)存
bool warning_printed; /* For reservations */
bool flush_coalesced_mmio;
bool global_locking;
uint8_t vga_logging_count;
MemoryRegion *alias;
hwaddr alias_offset;
int32_t priority;
bool may_overlap;
QTAILQ_HEAD(subregions, MemoryRegion) subregions;
QTAILQ_ENTRY(MemoryRegion) subregions_link;
QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
const char *name; //MemoryRegion的名字,調(diào)試時(shí)使用
uint8_t dirty_log_mask; //表示哪種dirty map被使用,共有三種
//IOevent文件描述符的管理
unsigned ioeventfd_nb;
MemoryRegionIoeventfd *ioeventfds;
NotifierList iommu_notify;
};
六、Qemu與其他虛擬機(jī)管理器對(duì)比
在虛擬化的廣袤天地里,Qemu 并非獨(dú)自閃耀,還有其他一些虛擬機(jī)管理器同樣備受關(guān)注,它們各自有著獨(dú)特的特點(diǎn)和優(yōu)勢(shì)。下面,我們就來(lái)深入對(duì)比一下 Qemu 與其他常見(jiàn)虛擬機(jī)管理器的異同。
6.1 Qemu與 KVM的協(xié)作與差異
KVM,即 Kernel-based Virtual Machine,是基于 Linux 內(nèi)核的虛擬化技術(shù) 。它利用硬件虛擬化擴(kuò)展(如 Intel VT 或 AMD-V)來(lái)實(shí)現(xiàn)高效的硬件輔助虛擬化,與 Qemu 有著緊密的聯(lián)系,同時(shí)也存在一些明顯的差異。
從協(xié)作的角度來(lái)看,KVM 和 Qemu 常常攜手合作,共同為用戶提供強(qiáng)大的虛擬化解決方案 。KVM 作為 Linux 內(nèi)核的一部分,提供了虛擬化的核心框架,負(fù)責(zé)管理 CPU 和內(nèi)存等關(guān)鍵資源的虛擬化 。而 Qemu 則作為用戶空間的工具,承擔(dān)起模擬各種硬件設(shè)備的重任,為虛擬機(jī)提供完整的硬件環(huán)境,如模擬網(wǎng)卡、硬盤(pán)、顯卡等設(shè)備,使得虛擬機(jī)能夠像運(yùn)行在真實(shí)硬件上一樣與外部環(huán)境進(jìn)行交互 。通過(guò)這種協(xié)作,KVM 和 Qemu 充分發(fā)揮各自的優(yōu)勢(shì),既利用了硬件虛擬化的高性能,又實(shí)現(xiàn)了豐富的硬件模擬功能,為用戶帶來(lái)了高效、靈活的虛擬化體驗(yàn)。
在性能方面,KVM 具有顯著的優(yōu)勢(shì) 。由于 KVM 依賴于硬件輔助虛擬化,它可以直接利用 CPU 的虛擬化擴(kuò)展,大大降低了虛擬化的開(kāi)銷(xiāo),使得虛擬機(jī)能夠以接近原生系統(tǒng)的性能運(yùn)行 。對(duì)于那些對(duì)性能要求極高的應(yīng)用場(chǎng)景,如大規(guī)模數(shù)據(jù)處理、高性能計(jì)算等,KVM 的優(yōu)勢(shì)尤為明顯 。相比之下,Qemu 在純軟件模擬模式下,由于所有的硬件模擬都通過(guò)軟件實(shí)現(xiàn),會(huì)產(chǎn)生較高的開(kāi)銷(xiāo),性能相對(duì)較低 。特別是在處理計(jì)算密集型任務(wù)時(shí),Qemu 可能會(huì)出現(xiàn)性能瓶頸 。然而,當(dāng) Qemu 與 KVM 結(jié)合使用時(shí),借助 KVM 的硬件加速功能,其性能會(huì)得到大幅提升 。
設(shè)備支持方面,Qemu 憑借其全系統(tǒng)仿真的特性,展現(xiàn)出了強(qiáng)大的兼容性 。它能夠模擬多種不同架構(gòu)的硬件設(shè)備,支持 x86、ARM、PowerPC、MIPS 等多種處理器架構(gòu),這使得 Qemu 在跨平臺(tái)開(kāi)發(fā)和測(cè)試中具有獨(dú)特的優(yōu)勢(shì) 。無(wú)論是開(kāi)發(fā)基于 x86 架構(gòu)的服務(wù)器應(yīng)用,還是基于 ARM 架構(gòu)的嵌入式系統(tǒng),Qemu 都能提供相應(yīng)的模擬環(huán)境 。而 KVM 的設(shè)備支持則相對(duì)局限于具有特定硬件虛擬化擴(kuò)展的系統(tǒng),主要適用于基于 x86 架構(gòu)的服務(wù)器場(chǎng)景 。雖然 KVM 也在不斷擴(kuò)展其設(shè)備支持范圍,但在跨平臺(tái)兼容性方面,與 Qemu 相比仍有一定差距 。
易用性上,Qemu 的使用相對(duì)較為簡(jiǎn)單直觀 。它提供了豐富的命令行參數(shù)和圖形化界面工具,用戶可以通過(guò)簡(jiǎn)單的配置和操作,快速創(chuàng)建和管理虛擬機(jī) 。而且,Qemu 對(duì)硬件的要求相對(duì)較低,即使在不支持硬件虛擬化的設(shè)備上也能運(yùn)行 。KVM 的使用則相對(duì)復(fù)雜一些,由于它與 Linux 內(nèi)核緊密集成,用戶需要對(duì) Linux 系統(tǒng)有一定的了解,并且需要確保硬件支持虛擬化擴(kuò)展 。不過(guò),隨著管理工具的不斷發(fā)展,如 virt-manager 等圖形化管理工具的出現(xiàn),KVM 的管理也變得越來(lái)越方便 。
6.2 Qemu與 libvirt 的功能區(qū)分
libvirt 是一個(gè)用于管理和控制虛擬化技術(shù)的工具集,它提供了統(tǒng)一的 API 和命令行工具,支持多種虛擬化技術(shù),包括 Qemu/KVM、Xen、LXC 等 。與 Qemu 相比,libvirt 在功能和定位上有著明顯的區(qū)別。
在虛擬機(jī)管理方式上,Qemu 主要通過(guò)命令行或者腳本來(lái)直接啟動(dòng)和管理虛擬機(jī) 。用戶需要熟悉 Qemu 的各種命令行參數(shù),手動(dòng)配置虛擬機(jī)的各項(xiàng)參數(shù),如內(nèi)存大小、CPU 核心數(shù)、磁盤(pán)映像文件等 。這種方式雖然靈活,但對(duì)于初學(xué)者來(lái)說(shuō)可能具有一定的難度 。而 libvirt 則提供了更為高級(jí)和抽象的管理方式 。它通過(guò) XML 配置文件來(lái)描述虛擬機(jī)的各種屬性和配置,用戶可以通過(guò)編輯 XML 文件或者使用 libvirt 提供的命令行工具(如 virsh)、圖形化界面工具(如 virt-manager)來(lái)管理虛擬機(jī) 。這種方式使得虛擬機(jī)的管理更加規(guī)范化和易于操作,尤其適合在生產(chǎn)環(huán)境中進(jìn)行大規(guī)模的虛擬機(jī)管理 。
從功能特點(diǎn)來(lái)看,Qemu 專(zhuān)注于硬件模擬和虛擬機(jī)的運(yùn)行,它提供了強(qiáng)大的設(shè)備模擬功能,能夠?yàn)樘摂M機(jī)提供逼真的硬件環(huán)境 。Qemu 還支持動(dòng)態(tài)二進(jìn)制翻譯等技術(shù),實(shí)現(xiàn)了跨架構(gòu)的虛擬化 。而 libvirt 則更側(cè)重于提供統(tǒng)一的管理接口和高級(jí)的管理功能 。它不僅可以管理虛擬機(jī)的生命周期,如創(chuàng)建、啟動(dòng)、暫停、關(guān)閉、刪除等操作,還提供了諸如虛擬機(jī)快照、遷移、資源監(jiān)控等高級(jí)功能 。通過(guò) libvirt,用戶可以方便地對(duì)多個(gè)虛擬機(jī)進(jìn)行集中管理,實(shí)現(xiàn)資源的動(dòng)態(tài)分配和優(yōu)化 。
舉個(gè)例子,在一個(gè)云計(jì)算數(shù)據(jù)中心中,管理員可能會(huì)使用 libvirt 來(lái)統(tǒng)一管理大量的虛擬機(jī),通過(guò) virsh 命令或者 virt-manager 界面,快速創(chuàng)建、部署和監(jiān)控虛擬機(jī) 。而在每個(gè)虛擬機(jī)內(nèi)部,Qemu 則負(fù)責(zé)模擬硬件設(shè)備,為虛擬機(jī)提供運(yùn)行環(huán)境,確保虛擬機(jī)中的操作系統(tǒng)和應(yīng)用程序能夠正常運(yùn)行 。
七、使用Qemu虛擬機(jī)管理器的優(yōu)勢(shì)
7.1靈活性與可定制性
Qemu 虛擬機(jī)管理器賦予用戶高度的自由,讓用戶能夠根據(jù)自己的需求隨心所欲地定制虛擬機(jī)的各種參數(shù) 。無(wú)論是設(shè)置虛擬機(jī)的 CPU 核心數(shù)、內(nèi)存大小,還是配置虛擬硬盤(pán)的容量和類(lèi)型,甚至是調(diào)整虛擬網(wǎng)卡的網(wǎng)絡(luò)配置,用戶都可以通過(guò)簡(jiǎn)單的命令行參數(shù)或者配置文件輕松實(shí)現(xiàn) 。例如,在進(jìn)行大數(shù)據(jù)處理的性能測(cè)試時(shí),用戶可以根據(jù)測(cè)試需求,將虛擬機(jī)的 CPU 核心數(shù)設(shè)置為 8 個(gè),內(nèi)存設(shè)置為 16GB,以模擬真實(shí)的大數(shù)據(jù)處理環(huán)境 。
這種高度的靈活性和可定制性,使得 Qemu 能夠滿足各種復(fù)雜的硬件虛擬化需求,無(wú)論是進(jìn)行簡(jiǎn)單的開(kāi)發(fā)測(cè)試,還是搭建復(fù)雜的云計(jì)算環(huán)境,Qemu 都能應(yīng)對(duì)自如 。而且,Qemu 還支持對(duì)虛擬機(jī)進(jìn)行動(dòng)態(tài)調(diào)整,用戶可以在虛擬機(jī)運(yùn)行過(guò)程中,根據(jù)實(shí)際需求動(dòng)態(tài)增加或減少 CPU 核心數(shù)、內(nèi)存大小等資源,無(wú)需重啟虛擬機(jī),大大提高了資源的利用率和使用效率 。
7.2廣泛的硬件和系統(tǒng)支持
Qemu 對(duì)硬件和操作系統(tǒng)的兼容性堪稱一絕 。它支持 x86、ARM、PowerPC、MIPS、RISC-V 等多種硬件架構(gòu),這使得開(kāi)發(fā)者可以在同一臺(tái)物理計(jì)算機(jī)上模擬不同架構(gòu)的硬件環(huán)境,進(jìn)行跨平臺(tái)的開(kāi)發(fā)和測(cè)試 。無(wú)論是開(kāi)發(fā)基于 x86 架構(gòu)的桌面應(yīng)用,還是基于 ARM 架構(gòu)的嵌入式系統(tǒng),Qemu 都能提供相應(yīng)的模擬環(huán)境 。
在操作系統(tǒng)支持方面,Qemu 同樣表現(xiàn)出色,它幾乎支持所有主流的操作系統(tǒng),如 Windows、Linux、macOS、FreeBSD、Solaris 等 。用戶可以在 Qemu 虛擬機(jī)中輕松安裝和運(yùn)行這些操作系統(tǒng),無(wú)需擔(dān)心兼容性問(wèn)題 。例如,安全研究人員可以利用 Qemu 創(chuàng)建一個(gè)包含 Windows 操作系統(tǒng)和各種應(yīng)用程序的虛擬機(jī),用于進(jìn)行惡意軟件分析和漏洞挖掘 。這種廣泛的硬件和系統(tǒng)支持,使得 Qemu 成為了開(kāi)發(fā)者和技術(shù)愛(ài)好者的得力助手,為他們的工作和研究提供了極大的便利 。
7.3強(qiáng)大的社區(qū)與生態(tài)
Qemu 擁有一個(gè)龐大且活躍的開(kāi)源社區(qū) 。在這個(gè)社區(qū)中,來(lái)自世界各地的開(kāi)發(fā)者和技術(shù)愛(ài)好者們積極參與 Qemu 的開(kāi)發(fā)和維護(hù),不斷為 Qemu 貢獻(xiàn)新的功能和特性 。社區(qū)成員們還會(huì)在社區(qū)論壇、郵件列表等平臺(tái)上分享自己的使用經(jīng)驗(yàn)、技術(shù)心得和解決方案,當(dāng)用戶在使用 Qemu 過(guò)程中遇到問(wèn)題時(shí),可以在社區(qū)中尋求幫助,往往能得到其他成員的熱心解答和支持 。
同時(shí),社區(qū)還提供了豐富的文檔資源,包括官方文檔、用戶手冊(cè)、教程等,這些文檔詳細(xì)介紹了 Qemu 的使用方法、工作原理和開(kāi)發(fā)指南,無(wú)論是初學(xué)者還是有經(jīng)驗(yàn)的用戶,都能從中獲取到有用的信息 。此外,Qemu 還有著豐富的生態(tài)系統(tǒng),它與許多其他開(kāi)源項(xiàng)目和工具緊密集成,如 KVM、libvirt、OpenStack 等 。這些集成使得 Qemu 的功能得到了進(jìn)一步擴(kuò)展和增強(qiáng),用戶可以根據(jù)自己的需求,選擇合適的工具和技術(shù)與 Qemu 搭配使用,構(gòu)建出更加完善的虛擬化解決方案 。