Qemu 是純軟件實現的虛擬化模擬器,幾乎能夠模擬任何硬件設備,咱們最熟悉的就是可以模擬一臺可以獨立運行操做系統的虛擬機,虛擬機認爲本身和硬件打交道,但實際上是和 Qemu 模擬出來的硬件打交道,Qemu 將這些指令轉譯給真正的硬件。git
正由於 Qemu 是純軟件實現的,全部的指令都要經 Qemu 過一手,性能很是低,因此,在生產環境中,大多數的作法都是配合 KVM 來完成虛擬化工做,由於 KVM 是硬件輔助的虛擬化技術,主要負責 比較繁瑣的 CPU 和內存虛擬化,而 Qemu 則負責 I/O 虛擬化,二者合做各自發揮自身的優點,相得益彰。ubuntu
從本質上看,虛擬出的每一個虛擬機對應 host 上的一個 Qemu 進程,而虛擬機的執行線程(如 CPU 線程、I/O 線程等)對應 Qemu 進程的一個線程。下面經過一個虛擬機啓動過程看看 Qemu 是如何與 KVM 交互的。centos
// 第一步,獲取到 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 軟件虛擬化實現的思路是採用二進制指令翻譯技術,主要是提取 guest 代碼,而後將其翻譯成 TCG 中間代碼,最後再將中間代碼翻譯成 host 指定架構的代碼,如 x86 體系就翻譯成其支持的代碼形式,ARM 架構同理。網絡
因此,從宏觀上看,源碼結構主要包含如下幾個部分:架構
/vl.c:最主要的模擬循環,虛擬機環境初始化,和 CPU 的執行。函數
/target-arch/translate.c:將 guest 代碼翻譯成不一樣架構的 TCG 操做碼。工具
/tcg/tcg.c:主要的 TCG 代碼。性能
/tcg/arch/tcg-target.c:將 TCG 代碼轉化生成主機代碼。優化
/cpu-exec.c:主要尋找下一個二進制翻譯代碼塊,若是沒有找到就請求獲得下一個代碼塊,而且操做生成的代碼塊。ui
其中,涉及的主要幾個函數以下:
知道了這個整體的代碼結構,再去具體瞭解每個模塊可能會相對容易一點。
1. 源碼下載
centos:sudo apt-get install qemu ubuntu:sudo yum install qemu -y 安裝包: $wget http://wiki.qemu-project.org/download/qemu-2.0.0.tar.bz2 $tar xjvf qemu-2.0.0.tar.bz2 Git: $git clone git://git.qemu-project.org/qemu.git
2. 編譯及安裝
$cd qemu-2.0.0 //若是使用的是git下載的源碼,執行cd qemu $./configure --enable-kvm --enable-debug --enable-vnc --enable-werror --target-list="x86_64-softmmu" $make -j8 $sudo make install
configure 腳本用於生成 Makefile,其選項能夠用 ./configure –help 查看。
這裏使用到的選項含義以下:
–enable-kvm:編譯 KVM 模塊,使 Qemu 能夠利用 KVM 來訪問硬件提供的虛擬化服務。
–enable-vnc:啓用 VNC。
–enalbe-werror:編譯時,將全部的警告看成錯誤處理。
–target-list:選擇目標機器的架構。默認是將全部的架構都編譯,但爲了更快的完成編譯,指定須要的架構便可。
安裝好以後,會生成以下應用程序:
ivshmem-client/server:這是一個 guest 和 host 共享內存的應用程序,遵循 C/S 的架構。
qemu-ga:這是一個不利用網絡實現 guest 和 host 之間交互的應用程序(使用 virtio-serial),運行在 guest 中。
qemu-io:這是一個執行 Qemu I/O 操做的命令行工具。
qemu-system-x86_64:Qemu 的核心應用程序,虛擬機就由它建立的。
qemu-img:建立虛擬機鏡像文件的工具,下面有例子說明。
qemu-nbd:磁盤掛載工具。
下面經過建立虛擬機操做來對這些工具備個初步的認識。
3. 建立虛擬機
虛擬機鏡像用來模擬虛擬機的硬盤,在啓動虛擬機以前須要建立鏡像文件。
qemu-img create -f qcow2 test-vm-1.qcow2 10G
-f 選項用於指定鏡像的格式,qcow2 格式是 Qemu 最經常使用的鏡像格式,採用來寫時複製技術來優化性能。test-vm-1.qcow2 是鏡像文件的名字,10G是鏡像文件大小。鏡像文件建立完成後,可以使用 qemu-system-x86 來啓動x86 架構的虛擬機:
qemu-system-x86_64 test-vm-1.qcow2
由於 test-vm-1.qcow2 中並未給虛擬機安裝操做系統,因此會提示 「No bootable device」,無可啓動設備。
qemu-system-x86_64 -m 2048 -enable-kvm test-vm-1.qcow2 -cdrom ./Centos-Desktop-x86_64-20-1.iso
-m 指定虛擬機內存大小,默認單位是 MB, -enable-kvm 使用 KVM 進行加速,-cdrom 添加 fedora 的安裝鏡像。可在彈出的窗口中操做虛擬機,安裝操做系統,安裝完成後重起虛擬機便會從硬盤 ( test-vm-1.qcow2 ) 啓動。以後再啓動虛擬機只須要執行:
qemu-system-x86_64 -m 2048 -enable-kvm test-vm-1.qcow2
qemu-img 支持很是多種的文件格式,能夠經過 qemu-img -h 查看
其中 raw 和 qcow2 是比較經常使用的兩種,raw 是 qemu-img 命令默認的,qcow2 是 qemu 目前推薦的鏡像格式,是功能最多的格式。這些知識後面會有文章來專門講述。