QEMU學習筆記(2020-12-03)

QEMU學習筆記

1 QEMU構建系統(tǒng)架構

1.1 Makefiles

QEMU 構建系統(tǒng)需要使用 GNU make。

QEMU 當前支持 VPATH 和非 VPATH 構建,因此有三種通用方式調用 configure 并執(zhí)行構建。

VPATH,完全在 QEMU 源碼樹之外構建產品

$ cd ../
$ mkdir build
$ cd build
$ ../qemu/configure
$ make

VPATH,在 QEMU 源碼樹的一個子目錄中構建產品

$ mkdir build
$ cd build
$ ../configure
$ make

非 VPATH,在任何地方構建產品

$ ./configure
$ make

QEMU 的維護者通常建議開發(fā)者使用 VPATH 構建。QEMU 的補丁期待確保 VPATH 構建依然有效。

1.2 模塊結構

QEMU 構建系統(tǒng)有大量的重要輸出:

  • 工具 - qemu-img,qemu-nbd,qga (guest agent),等等
  • 系統(tǒng)模擬器 - qemu-system-$ARCH
  • 用戶空間模擬器 - qemu-$ARCH
  • 單元測試

源碼是高度模塊化的,分割多個文件,以便盡可能少地重復編譯所有這些組件??梢哉J為是兩個不同的文件組,包括獨立于 QEMU 仿真目標的文件和依賴于QEMU 仿真目標的文件組。

獨立于仿真目標的文件集合中是各種通用輔助代碼,比如錯誤處理基礎設施,標準數據結構,平臺移植性封裝函數,等等。這些代碼可以只被編譯一次,而把它們的 .o 文件鏈接到所有的輸出二進制文件。

依賴于仿真目標的文件集合中是 CPU 模擬,設備模擬和許多膠水代碼。這有時還不得不編譯多次,為每個目標編譯一次。

所有二進制文件都用到的實用代碼被編譯為一個稱為 libqemuutil.a 靜態(tài)包,它會被鏈接進所有的二進制文件。為了提供只有一部分二進制文件需要的鉤子,libqemuutil.a 中的代碼可能依賴于其它不完全由 QEMU 二進制實現的函數。為了處理這種情況,還有另一個稱為 libqemustub.a 的庫,它為所有這些函數提供了 dummy stubs。如果沒有真正的實現,則它們將被延遲鏈接進二進制中。以這種方式,libqemustub.a 靜態(tài)庫可以被看作一個弱符號概念的可移植實現。所有的二進制文件應該同時鏈接 libqemuutil.a 和 libqemustub.a。比如

 qemu-img$(EXESUF): qemu-img.o ..snippet.. libqemuutil.a libqemustub.a

1.3 目標變量命名

QEMU 用約定變量來列出不同的目標文件組的。它們的命名約定為 $PREFIX-obj-y。比如,libqemuutil.a 文件將與變量 util-obj-y 列出的所有目標文件鏈接。因此,比如,util/Makefile.obj 將包含一系列看起來像這樣的定義:

  util-obj-y += bitmap.o bitops.o hbitmap.o
  util-obj-y += fifo8.o
  util-obj-y += acl.o
  util-obj-y += error.o qemu-error.o

當有一個目標文件需要基于主機系統(tǒng)的一些特性有條件地構建時,配置腳本將條件定義一個變量。比如,在 Windows 上它將定義 $(CONFIG_POSIX) 值為 'n',而 $(CONFIG_WIN32) 值為 'y'?,F在可以在列出目標文件時使用配置變量了。比如,

  util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
  util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o

在 Windows 上被擴展為

  util-obj-y += oslib-win32.o qemu-thread-win32.o
  util-obj-n += oslib-posix.o qemu-thread-posix.o

由于 libqemutil.a 被鏈接進 $(util-obj-y) ,在 Windows 平臺構建中,$(util-obj-n) 中列出的 POSIX 特有文件被忽略。

2 模塊的注冊與加載

2.1 模塊的注冊

QEMU 4.2.0 版本的入口在 vl.cmain函數中,其中在vl.c的 2885 行是module_call_init(MODULE_INIT_QOM);

module_call_initinclude/qemu/module.h中聲明,在util/module.c中定義,其作用是遍歷init_type_list[MODULE_INIT_QOM]調用所有已注冊 QOM(QEMU Object Module) 模塊的init函數,完成 QOM 模塊的初始化。

QOM 模塊的注冊在每個模塊文件末尾的type_init中進行,type_init通過include/qemu/module.h#module_init宏定義的__attribute__((constructor))將注冊函數轉換成構造函數,在運行main入口函數之前完成注冊。

hw/virtio/virtio-blk-pci.c為例,module_call_init會調用init,而init實際指向virtio_blk_pci_register, virtio_blk_pci_register最終會將設備對應的TypeImpl注冊到哈希表中(以TypeInfo的name屬性為索引)

2.2 參數解析

兩次循環(huán)中解析argv,將解析結果保存到QemuOpts鏈表中

2.3 模塊加載

1. 在main函數中會遍歷指定的-device參數,然后調用device_init_func來做設備的初始化。

2. 會依次調用device_init_func-> qdev_device_add -> object_new -> object_initialize_with_type。主要的初始化工作都是在object_initialize_with_type中完成的。

3. 首先會調用type_initialize完成類的初始化。在類的初始化中會設置類的realize回調函數為virtio_balloon_pci_realize。該函數在做類對象的實例化的時候會調用。

4. 之后會調用object_init_with_type做類對象的初始化。會遞歸從父對象開始執(zhí)行instance_init。TYPE_DEVICE的instance_init函數為device_initfn。該函數調用執(zhí)行了object_property_add_bool增加了三個屬性。其中realized屬性是當設置了對象真正創(chuàng)建的時候調用的。其set回調函數設置為device_set_realized。任何一個設備創(chuàng)建的時候都會調用該函數。

image

5. 設備類和對象實例初始化完成后會回到qdev_device_add函數,接下來就會進行具體的設備實現過程。

6. 調用object_property_set_bool將realized屬性設置為true,從而會調用剛才設置的回調函數device_set_realized。

7. 會首先調用DeviceClass的realize函數即virtio_pci_dc_realize。該函數是在virtio_pci_class_init中設置的。

image

8. 父類的realize函數會一次調用子類的realize函數。接著會調用PCIDeviceClass的realize函數即pci_qdev_realize。

9. 然后依次調用VirtioPCIClass、VirtioBalloonPCIClass的realize函數。從而實現了VirtioBalloonPCI設備的創(chuàng)建。最后還需要創(chuàng)建VirtioBalloon設備,將其掛載到PCI總線上。

10. 即依次調用VirtioDeviceClass、VirtioBalloonDeviceClass的realize函數。VirtioBalloon設備的具體實現就是在函數virtio_balloon_device_realize中。

整個流程如下圖所示,類之間的調用流則如類繼承關系圖中紅線所示。

image

在virtio_balloon_device_realize中,調用virtio_add_queue為設備添加了三個virtqueue。其中兩個的回調處理函數為virtio_ballon_handle_output,另一個是virtio_balloon_receive_stats。從而構建了從設備的輸入輸出通道,以及當收到輸入輸出信息時調用的回調處理函數。

image

至此設備創(chuàng)建完成,但是還差最后一步將設備掛載到virtio總線上去。該步驟是在函數virtio_device_realize中實現的。該函數調用vdc->realize創(chuàng)建了具體設備后,會調用virtio_bus_device_plugged,該函數的作用就是將virtio設備插入到virtio總線。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容