官术网_书友最值得收藏!

2.3 QEMU參數解析

本節對QEMU參數解析進行簡要介紹,幫助讀者將QEMU命令行參數與其代碼中的實現聯系起來,方便閱讀代碼,但是由于參數解析并非本書重點,因此不會對具體的細節進行深入講解。本節使用的QEMU命令如下。

QEMU使用QEMUOption來表示QEMU程序的參數選項,其定義如下。

其中,name表示參數選項的名字;flags表示選項中一些參數選項的屬性,比如是否有子參數;arch_mask表示參數支持的體系結構。

vl.c在全局范圍定義了一個qemu_options,存儲了所有的可用選項,main函數中會調lookup_opt來解析QEMU命令行參數,不在qemu_options中的參數是不合法的。

qemu_options的生成使用QEMU_OPTIONS_GENERATE_OPTIONS編譯控制選項以及一個文件qemu-options-wrapper.h填充。在qemu-options-wrapper.h中,根據是否定義QEMU_OPTIONS_GENERATE_ENUM,QEMU_OPTIONS_GENERATE_HELP,QEMU_OPTIONS_GENERATE_OPTIONS以及qemu-options.def文件可以生成不同的內容。qemu-options.def是在Makefile中利用scripts/hxtool腳本根據qemu-options.hx文件生成的。

在這里只需要理解qemu_options中包括了所有可能的參數選項,如上面的-enable-kvm、-smp、-realtime、-device等即可。圖2-13顯示了gdb中部分qemu_options的值。

圖2-13 QEMU參數選項

QEMUOption提供了參數的基本信息情況。實際參數的保存是由3個數據結構完成的。

QEMU將所有參數分成了幾個大選項,如-eanble-kvm和-kernel都屬于machine相關的,每一個大選項使用結構體QemuOptsList表示,QEMU在qemu-config.c中定義了vm_config_groups。

這表示可以支持48個大選項。在main函數中用qemu_add_opts將各個QemuOptsList添加到vm_config_groups中。

每個QemuOptsList存儲了大選項支持的所有小選項,如-realtime大選項定義如下。

-realtime只支持一個值為bool的子選項,即只能有-realtime mlock=on/off。但是像-device這種選項就沒有這么死板了,-device并沒有規定必需的選項,因為設備有無數多種,不可能全部進行規定,解析就是按照“,”或者“=”來進行的。每個子選項由一個QemuOpt結構表示,定義如下。

name表示子選項的字符串表示;str表示對應的值。

QemuOptsList并不和QemuOpt直接聯系,中間還需要有一層QemuOpts,這是因為QEMU命令行可以指定創建兩個相同的設備,此時這類設備都在QemuOptsList的鏈表上,這是兩個獨立QemuOpts,每個QemuOpts有自己的QemuOpt鏈表。QemuOpts結構如下。

head是QemuOpts下的QemuOpt鏈表頭;next用來連接相同QemuOptsList下同一種Qemu Opts。

QemuOptsList、QemuOpts與QemuOpt三者的關系如圖2-14所示。

圖2-14 QemuOptsList、QemuOpts與QemuOpt三者關系

這里以-device參數項為例簡單分析參數的處理過程,vl.c中的main函數中有一個很長的for循環來解析參數,當解析到"-device"時,下面是對QEMU_OPTION_device的分支處理。

qemu_find_opts函數從全局變量vm_config_groups中找到剛才插入的device QemuOptsList并返回。qemu_opts_parse_noisily函數只是簡單調用了opts_parse,后者解析出一個QemuOpts,每一個大類的參數(如-device edu)都會在相應的QemuOptsList下面構造處理一個Opts。

opts_parse函數調用的最重要的兩個函數是qemu_opts_create和opts_do_parse,前者用來創建opts并且將它插入到QemuOptsList上,后者則開始解析出一個一個的QemuOpt。opts_do_parse的作用就是解析參數的值,如本節開始的命令行參數ivshmem,shm=ivshmem,size=1。QEMU的參數可以有多種情況,比如foo,bar中foo表示開啟一個flag,也有可能類似于foo=bar,對此opts_do_parse需要處理各種情況,并對每一個值生成一個QemuOpt。關鍵代碼如下。

該函數首先根據各種情況(foo,bar或者foo=bar,more)解析出option以及value,然后調用opt_set,在該函數中會分配一個QemuOpt結構,并且進行初始化。例子中的ivshmem,shm=ivshmem, size=1會解析出3個QemuOpt,name=str分別是driver=ivshmem、shm=ivshmem、size=1。所以對于兩個device的參數解析會形成圖2-15所示的鏈表。

圖2-15 QEMU參數解析結果

主站蜘蛛池模板: 揭阳市| 平阴县| 盐池县| 灌南县| 中阳县| 木里| 巴东县| 磐石市| 南华县| 扬州市| 徐汇区| 奇台县| 成安县| 南城县| 东乌珠穆沁旗| 宝应县| 同江市| 吕梁市| 东乌珠穆沁旗| 漠河县| 扎赉特旗| 济南市| 濮阳县| 灵石县| 正镶白旗| 潼关县| 油尖旺区| 南澳县| 北宁市| 读书| 盐边县| 祥云县| 灵武市| 安宁市| 咸丰县| 城步| 三台县| 灵川县| 东城区| 自治县| 大同县|