转发请注明: http://blog.163.com/eric_liufeng/blog/static/197382683201565053403
基于QEMU2.0.0
QDEV初始化整体原理:
? step0: 在main前面,通过type_init->module_init来完成设备模块初始化函数mc146818rtc_register_types的注册
? step1: 在main中,首先调用module_call_init(MODULE_INIT_QOM)完成各个设备模块的初始化(mc146818rtc_register_types),并注册设备类的class_init函数
? step3: 设备的入口点,在machine->init的时候初始化不同设备的init入口函数,参见pc_init1中的xx_init
? step4: 先建立一个ISA的RTC设备,并调用class_init注册realized函数,其中class_init已经在main函数前就完成了注册
? step5: 调用对象已注册的realize函数实例化该虚拟设备,设定虚拟设备结构体的虚拟寄存器等
static void rtc_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
/* 注册函数 device_set_realized
-> pc_init_pci
-> pc_init1
-> pc_basic_device_init
-> rtc_init (step3: 设备的入口点,在machine->init的时候初始化不同设备的init入口函数,参加pc_init1中的xx_init)
-> isa_create (step4: 先建立一个ISA的RTC设备,并调用class_init注册realized函数,其中class_init已经在main函数前就完成了注册)
-> qdev_create
-> qdev_try_create
-> object_new
-> object_new_with_type
-> object_initialize_with_type (step 4.2)
-> object_init_with_type
-> instance_init(=device_initfn)
-> pc_init1
-> pc_basic_device_init
-> rtc_init
-> qdev_init_nofail (step5: 调用对象已注册的realize函数实例化该虚拟设备,设定虚拟设备结构体的虚拟寄存器等)
-> qdev_init
-> object_property_set_bool
-> object_property_set_qobject
-> object_property_set
-> prop->set(=device_set_realized)
-> dc->realize(=rtc_realizefn) //此时realize已经复制完成
*/
dc->realize = rtc_realizefn;
dc->vmsd = &vmstate_rtc;
dc->props = mc146818rtc_properties;
/* Reason: needs to be wired up by rtc_init() */
dc->cannot_instantiate_with_device_add_yet = true;
}
static const TypeInfo mc146818rtc_info = {
.name = TYPE_MC146818_RTC,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(RTCState),
/*
-> rtc_init
-> isa_create
-> qdev_create
-> qdev_try_create
-> object_new
-> object_new_with_type
-> type_initialize (step 4.1)
-> class_init
*/
.class_init = rtc_class_initfn,
};
/*
* step1: 在main中,首先调用module_call_init(MODULE_INIT_QOM)完成各个设备模块的初始化,并注册设备类的class_init函数
* -> main
* -> module_call_init(MODULE_INIT_QOM)
* -> mc146818rtc_register_types
*/
static void mc146818rtc_register_types(void)
{
type_register_static(&mc146818rtc_info);
}
/*
* step0: 在main前面,通过type_init->module_init来完成设备模块初始化函数mc146818rtc_register_types的注册
*
* 注册设备模块,将mc146818rtc_register_types初始化为该设备模块的init方法
* 是在vl.c文件的main()函数之前调用的
*/
type_init(mc146818rtc_register_types)
在vl.c的main中
1. moudle_init注册各种模型
2. 分析参数
3. 根据参数加入各种设备
3. machine->init(¤t_machine->init_args);
5. 根据incoming处理load