qemu中的module

来源:互联网 发布:java多线程编程项目 编辑:程序博客网 时间:2024/05/15 04:15
qemu采用了模块机制。总共有5中模块定义在include/qemu/module.h 中typedef enum {    MODULE_INIT_BLOCK,    MODULE_INIT_OPTS,    MODULE_INIT_QAPI,    MODULE_INIT_QOM,    MODULE_INIT_TRACE,    MODULE_INIT_MAX} module_init_type;#define block_init(function) module_init(function, MODULE_INIT_BLOCK)#define opts_init(function) module_init(function, MODULE_INIT_OPTS)#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)#define type_init(function) module_init(function, MODULE_INIT_QOM)#define trace_init(function) module_init(function, MODULE_INIT_TRACE)这里以block为例static BlockDriver bdrv_archipelago = {    .format_name         = "archipelago",    .protocol_name       = "archipelago",    .instance_size       = sizeof(BDRVArchipelagoState),    .bdrv_parse_filename = archipelago_parse_filename,    .bdrv_file_open      = qemu_archipelago_open,};static void bdrv_archipelago_init(void){    bdrv_register(&bdrv_archipelago);}block_init(bdrv_archipelago_init);可见所以的block模块都会调用block_init。#define block_init(function) module_init(function, MODULE_INIT_BLOCK)block_init 会调用module_init,只是type是MODULE_INIT_BLOCK#define module_init(function, type)                                         \static void __attribute__((constructor)) do_qemu_init_ ## function(void)    \{                                                                           \    register_module_init(function, type);                                   \}可以看待所以的门口最终都会调用register_module_init,只是type不一样void register_module_init(void (*fn)(void), module_init_type type){    ModuleEntry *e;    ModuleTypeList *l;//申请一个ModuleEntry结构    e = g_malloc0(sizeof(*e));//申请模块最重要的函数。最后会在module_call_init中被调用到    e->init = fn;    e->type = type;//找到当前type的list    l = find_type(type);//插入到这个list的最后    QTAILQ_INSERT_TAIL(l, e, node);}继续看看find_typestatic ModuleTypeList *find_type(module_init_type type){//初始化数组init_type_list。建立前面说的5中type的list的head    init_lists();//每个不同的module type用init_type_list数组的index表示这中类型type的head    return &init_type_list[type];}与注册类似,会通过module_call_init来调用这5中模块的init函数void module_call_init(module_init_type type){    ModuleTypeList *l;    ModuleEntry *e;    l = find_type(type);    QTAILQ_FOREACH(e, l, node) {        e->init();    }}


原创粉丝点击