本文首發於個人公衆號 Linux雲計算網絡(id: cloud_dev),專一於乾貨分享,號內有 10T 書籍和視頻資源,後臺回覆 「1024」便可領取,歡迎你們關注,二維碼文末能夠掃。
Qemu 是純軟件實現的虛擬化模擬器,幾乎能夠模擬任何硬件設備,咱們最熟悉的就是可以模擬一臺可以獨立運行操做系統的虛擬機,虛擬機認爲本身和硬件打交道,但實際上是和 Qemu 模擬出來的硬件打交道,Qemu 將這些指令轉譯給真正的硬件。git
正由於 Qemu 是純軟件實現的,全部的指令都要經 Qemu 過一手,性能很是低,因此,在生產環境中,大多數的作法都是配合 KVM 來完成虛擬化工做,由於 KVM 是硬件輔助的虛擬化技術,主要負責 比較繁瑣的 CPU 和內存虛擬化,而 Qemu 則負責 I/O 虛擬化,二者合做各自發揮自身的優點,相得益彰。編程
從本質上看,虛擬出的每一個虛擬機對應 host 上的一個 Qemu 進程,而虛擬機的執行線程(如 CPU 線程、I/O 線程等)對應 Qemu 進程的一個線程。下面經過一個虛擬機啓動過程看看 Qemu 是如何與 KVM 交互的。ubuntu
// 第一步,獲取到 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 架構同理。centos
因此,從宏觀上看,源碼結構主要包含如下幾個部分:網絡
其中,涉及的主要幾個函數以下:架構
函數 | 路徑 | 註釋 |
---|---|---|
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 代碼 |
知道了這個整體的代碼結構,再去具體瞭解每個模塊可能會相對容易一點。函數
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
$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 查看。工具
這裏使用到的選項含義以下:oop
安裝好以後,會生成以下應用程序:性能
下面經過建立虛擬機操做來對這些工具備個初步的認識。
虛擬機鏡像用來模擬虛擬機的硬盤,在啓動虛擬機以前須要建立鏡像文件。
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 目前推薦的鏡像格式,是功能最多的格式。這些知識後面會有文章來專門講述。
公衆號後臺回覆「加羣」,帶你進入高手如雲交流羣
個人公衆號 「Linux雲計算網絡」(id: cloud_dev) ,號內有 10T 書籍和視頻資源,後臺回覆 「1024」 便可領取,分享的內容包括但不限於 Linux、網絡、雲計算虛擬化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++編程技術等內容,歡迎你們關注。