您的位置:首页 > 其它

QEMU(基于QEMU 2.0.0)设备初始化流程 - realizefn 调用流程(以 RTC为例)

2015-09-28 09:55 429 查看
转发请注明: 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

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: