QEMU虚拟机源码分析概论
QEMU官網描述
QEMU的官網首頁上對其自身的描述如下(請特別注意標紅字的部分):
QEMU is a generic and open source machine emulator and virtualizer.
When used as a machine emulator, QEMU can run OSes and programs made for one machine (e.g. an ARM board) on a different machine (e.g. your own PC). By using dynamic translation, it achieves very good performance.
When used as a virtualizer, QEMU achieves near native performance by executing the guest code directly on the host CPU. QEMU supports virtualization when executing under the Xen hypervisor or using the KVM kernel module in Linux. When using KVM, QEMU can virtualize x86, server and embedded PowerPC, and S390 guests.
QEMU is a member of Software Freedom Conservancy.
以上描述說明了QEMU的以下幾個特點:
1. QEMU可以被當作模擬器,也可以被當作虛擬機。
2. 當QEMU被當作模擬器時,我們可以在一臺機器上通過模擬設備,運行針對不同于本機上CPU的程序或者操作系統。(使用了動態翻譯技術,在我們的虛擬化環境中并沒有使用,因此不展開敘述)
3. 當QEMU被當作虛擬機使用時,QEMU必須基于Xen Hypervisor或者KVM內核模塊才能支持虛擬化。在這種條件下QEMU虛擬機可以通過直接在本機CPU上運行客戶機代碼獲得接近本機的性能。
QEMU與KVM的關系
當QEMU在模擬器模式下,運行操作系統時,我們可以認為這是一種軟件實現的虛擬化技術,它的效率比真機差很多,用戶可以明顯地感覺出來。當QEMU在虛擬機模式下,QEMU必須在Linux上運行,并且需要借助KVM或者Xen,利用Intel或者Amd提供的硬件輔助虛擬化技術,才能使虛擬機達到接近真機的性能。QEMU與KVM內核模塊協同工作,在虛擬機進程中,各司其職,又相互配合,最終實現高效的虛擬機應用。
QEMU與KVM的關系如下:
KVM在物理機啟動時創建/dev/kvm設備文件,當創建虛擬機時,KVM為該虛擬機進程創建一個VM的文件描述符,當創建vCPU時,KVM為每個vCPU創建一個文件描述符。同時,KVM向用戶空間提供了一系列針對特殊設備文件的ioctl系統調用。QEMU主要是通過ioctl系統調用與KVM進行交互的。
那么QEMU和KVM具體都實現了哪些功能呢?我們用一張圖說明:
QEMU所實現的功能包括:虛擬機的配置和創建、虛擬機運行依賴的虛擬設備、虛擬機運行時用戶操作環境和交互(vnc)以及一些針對虛擬機的特殊技術(如動態遷移),都是QEMU自己實現的。同時QEMU還實現了利用KVM提供的接口實現虛擬機硬件加速。
而KVM的主要功能在于初始化CPU硬件,打開虛擬化模式,然后將虛擬客戶機運行在虛擬機模式下,并對虛擬客戶機的運行提供支持,這些支持主要是以針對相關的特殊設備文件的ioctl系統調用。外設的模擬一般不會由KVM負責,只有對性能要求較高的虛擬設備,如虛擬中斷控制器和虛擬時鐘,是由KVM模擬的,這樣可以大量減少處理器的模式轉換的開銷。
QEMU的代碼結構
線程事件驅動模型
QEMU的體系結構正如上圖展示的——每個vCPU都是一個線程,這些vCPU線程可以運行客戶機的代碼,以及虛擬中斷控制器、虛擬時鐘的模擬。而Main loop主線程則是Event-driver的,通過輪詢文件描述符,調用對應的回調函數,處理由Monitor發出的命令、Timers超時,并且實現VNC、完成IO等功能。
QEMU事件驅動的代碼主要可以查看include/qemu/main-loop.h,以及相關的實現代碼。
設備模擬
QEMU為了實現大量設備的模擬,實現了比較完備的面向對象模型——QOM(QEMU Object Model)。QEMU對于CPU、內存、總線以及主板的模擬都是依賴于QOM的,QEMU中設備相關的數據結構的初始化工作都是依賴于QOM的初始化實現機制。對于它的實現主要可以查看include/qom/object.h。對于具體的CPU、內存等設備的模擬,可以查看include/qom/cpu.h、include/exec/memory.h、include/hw/qdev-core.h
QEMU中的虛擬機管理命令
QEMU中可以使用hmp command對虛擬機進行管理,在虛擬機環境中同時按住ctrl、Alt、2就可以進入QEMU的命令模式。通過輸入命令,就可以進行虛擬機的管理。比如savevm命令可以把虛擬機的當前狀態保存到虛擬機的磁盤中。這些命令的實現函數都有一個統一的命名方式:hmp_xxx,比如hmp_savevm就是savevm的實現函數的起始位置,hmp_migrate就是migrate的實現函數的起始位置。
因此對于QEMU中的每一條命令都可以很快找到相關的實現函數。
塊操作
QEMU實現了大量的塊設備驅動,從而支持了包括qcow2、qed、raw等格式的鏡像,這些格式的實現代碼都在block的文件夾下以及主目錄下的block.c中。QEMU設計了BlockDriver數據結構,其中包含了大量的回調函數指針,對于每一種磁盤格式,都有一個對應的BlockDriver的對象,并且實現了BlockDriver中的回調函數,然后將這個BlockDriver的對象注冊,即添加到一個全局的BlockDriver的鏈表中。
QEMU源碼編譯
QEMU的編譯過程并不復雜,首先進入QEMU的代碼目錄后,首先運行./configure –help,查看qemu支持的特性。然后選擇相關的特性進行編譯。
由于我們使用的X86_64的平臺,并且主要查看的是QEMU與KVM協同工作實現虛擬化的代碼,我們使用下列命令配置:
./configure –enable-debug –enable-kvm –target-list=x86_64-softmmu
上述命令會生成Makefile文件,然后直接make就可以了,為了加速編譯可以使用多線程:make -j number。
./configure命令運行時會檢查物理機的環境,檢查需要的相關的庫是否已經安裝在宿主機上。因此可能由于相關庫沒有安裝而中斷,其中一些庫包括:
pkg-config、zlib1g-dev、libglib2.0-dev、libpixman-1-dev、make等
以上庫都可以通過ubuntu的包管理命令apt-get install直接安裝。
如果需要把QEMU安裝到系統中可以使用make install命令。
閱讀代碼的工具準備
閱讀代碼的工具包括vim、ctags、gdb。
其中ctags會維持一個全局的tag表。通過在源代碼主目錄下使用ctags –R,可以生成對應的tag表的文件,文件名為tags。在打開一個源代碼文件后,用戶通過將光標移動到某一個函數調用或者數據結構的位置,同時按住ctrl+],就可以跳轉到函數或者數據結構的定義處,如果函數或者數據結構有多個定義,在vim中輸入:tn可以看下一個函數的定義。通過ctrl+t可以跳轉回原來的位置。另外,如果vim顯示沒有找到tags文件,需要顯式地告知vim,tags的路徑,命令:set tags=$tagspath。
總結
以上是生活随笔為你收集整理的QEMU虚拟机源码分析概论的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三种方式获取大疆照片的EXIF/XMP信
- 下一篇: 微信小程序-获取用户信息【梳理历史】