module_call_init(MODULE_INIT_QOM); //初始化设备 qemu_add_opts //初始化默认选项
module_call_init(MODULE_INIT_MACHINE); //初始化机器类型 machine = find_default_machine(); //这里对machine赋值,下面还会通过参数更改machine
vtp_script_execute(g_qemu_start_hook_path, g_fairsched_string, TYPE_START); //开机启动脚本的调用 深度分析启动参数 bdrv_init_with_whitelist -> bdrv_init ->
module_call_init(MODULE_INIT_BLOCK); //初始化BLOCK设备 machine->init(&args); //初始化machine
qemu_run_machine_init_done_notifiers(); //初始化成功回调通知 qemu_system_reset(VMRESET_SILENT);//system reset 启动运行 if (loadvm) { load_vmstate(loadvm); } else if (loadstate) { load_state_from_blockdev(loadstate); } resume_all_vcpus(); main_loop(); //进入主循环 }
Void main() {
module_call_init(MODULE_INIT_QOM);//初始化设备 qemu_add_opts//初始化默认选项
module_call_init(MODULE_INIT_MACHINE);//初始化机器类型
machine=find_default_machine();//这里对machine赋值,下面还会通过参数更改machine vtp_script_execute(g_qemu_start_hook_path,g_fairsched_string,TYPE_START);//开机启动脚本的调用 深度分析启动参数
bdrv_init_with_whitelist->bdrv_init->module_call_init(MODULE_INIT_BLOCK);//初始化BLOCK设备
machine->init(&args);//初始化machine
}
qemu_run_machine_init_done_notifiers();//初始化成功回调通知 qemu_system_reset(VMRESET_SILENT);//system reset 启动运行 if(loadvm){
load_vmstate(loadvm); }elseif(loadstate){
load_state_from_blockdev(loadstate); }
resume_all_vcpus();
main_loop();//进入主循环
在main函数进来的时候,首先调用module_call_init(MODULE_INIT_QOM);
void module_call_init(module_init_type type) { ModuleTypeList *l; ModuleEntry *e; l = find_type(type); QTAILQ_FOREACH(e, l, node) { e->init(); //这里,就是调用刚才注册的回调,例如,对于kvm-pit来说,调用的是pit_register } }
voidmodule_call_init(module_init_typetype) {
ModuleTypeList*l; ModuleEntry*e; l=find_type(type); QTAILQ_FOREACH(e,l,node){
e->init();//这里,就是调用刚才注册的回调,例如,对于kvm-pit来说,调用的是pit_register } }
此module_call_init将依次调用注册的回调,如PIT的pit_register_types:
static const TypeInfo pit_info = {
.name = \做为type_table的key
.parent = \父类型,这个比较重要,如果本TypeInfo没有设置class_size,会根据parent获取parent TypeImpl的class_size
.instance_size = sizeof(PITCommonState),//分配实例的大小 .class_init = pit_class_init, //初始化函数 };
static void pit_register_types(void) { type_register_static(&pit_info); }
Static const TypeInfopit_info = {
.name =\做为type_table的key
.parent =\//父类型,这个比较重要,如果本TypeInfo没有设置class_size,会根据parent获取parent TypeImpl的class_size
.instance_size=sizeof(PITCommonState),//分配实例的大小 .class_init=pit_class_init, //初始化函数 };
Static void pit_register_types(void) {
type_register_static(&pit_info); }
pit_register_types又进一步调用type_register_static -> type_register -> type_register_internal,这个函数完成的功能其实只是在qom\\object.c的type_table里插入了一个HASH键值 对,以TypeInfo的name为KEY,malloc了一个TypeInfo结构的超集TypeImpl为VALUE,在以name为KEY回溯 parent时需要TypeImpl,其实这个hash也可以做成一个tree。
QOM的Object模型
以pit为例,通过回溯parent你可以看到,其定义TypeInfo最终形成一个继承关系:
\-> \-> \-> \-> \qom\\object.c
static TypeInfo object_info = { .name = \
.instance_size = sizeof(Object), .instance_init = object_instance_init, .abstract = true, };
Static TypeInfo object_info={ .name=\
.instance_size=sizeof(Object), .instance_init=object_instance_init, .abstract=true, };
hw\\qdev.c
static const TypeInfo device_type_info = { .name = \sizeof(DeviceState), .instance_init = device_initfn, .instance_finalize = device_finalize, .class_base_init = device_class_base_init, .class_init =
device_class_init, .abstract = true, .class_size = sizeof(DeviceClass), };
staticconstTypeInfodevice_type_info={ .name=\ .parent=\
.instance_size=sizeof(DeviceState), .instance_init=device_initfn,
.instance_finalize=device_finalize,
.class_base_init=device_class_base_init, .class_init=device_class_init, .abstract=true,
.class_size=sizeof(DeviceClass), };
hw\\isa-bus.c
static const TypeInfo isa_device_type_info = { .name = \sizeof(ISADevice), .abstract = true, .class_size =
sizeof(ISADeviceClass), .class_init = isa_device_class_init, };
staticconstTypeInfoisa_device_type_info={ .name=\ .parent=\
.instance_size=sizeof(ISADevice), .abstract=true,
.class_size=sizeof(ISADeviceClass), .class_init=isa_device_class_init, };
hw\\i8254_common.c
static const TypeInfo pit_common_type = { .name = \sizeof(PITCommonState), .class_size =