基于qemu-7.1.0

tcg_accel_class初始化

accel/tcg/tcg-all.c:210

static void tcg_accel_class_init(ObjectClass *oc, void *data) // 初始化tcg加速器类
{
    AccelClass *ac = ACCEL_CLASS(oc);
    ac->name = "tcg";
    ac->init_machine = tcg_init_machine;
    ac->allowed = &tcg_allowed;

    object_class_property_add_str(oc, "thread",
                                  tcg_get_thread,
                                  tcg_set_thread);

    object_class_property_add(oc, "tb-size", "int",
        tcg_get_tb_size, tcg_set_tb_size,
        NULL, NULL);
    object_class_property_set_description(oc, "tb-size",
        "TCG translation block cache size");

    object_class_property_add_bool(oc, "split-wx",
        tcg_get_splitwx, tcg_set_splitwx);
    object_class_property_set_description(oc, "split-wx",
        "Map jit pages into separate RW and RX regions");
}

往前追踪函数调用

accel/tcg/tcg-all.c:233

static const TypeInfo tcg_accel_type = { // 往前追踪到这里
    .name = TYPE_TCG_ACCEL,
    .parent = TYPE_ACCEL,
    .instance_init = tcg_accel_instance_init,
    .class_init = tcg_accel_class_init,
    .instance_size = sizeof(TCGState),
};
module_obj(TYPE_TCG_ACCEL);

static void register_accel_types(void)
{
    type_register_static(&tcg_accel_type); // 再追踪
}

type_init(register_accel_types); // this way #define type_init(function) module_init(function, MODULE_INIT_QOM)

再追踪module_init函数

include/qemu/module.h:28

#define module_init(function, type)                                         \\
static void __attribute__((constructor)) do_qemu_init_ ## function(void)    \\
{                                                                           \\
    register_dso_module_init(function, type);                               \\
}
#else
/* This should not be used directly.  Use block_init etc. instead.  */
#define module_init(function, type)                                         \\
static void __attribute__((constructor)) do_qemu_init_ ## function(void)    \\
{                                                                           \\
    register_module_init(function, type);                                   \\
}
#endif

可以看出这个是一个接口,用来注册初始化的

这里分析一下是怎么写的

__attribute__((constructor)) 是GCC特有的属性,表示这个函数会在main()执行之前自动调用,相当于C++的全局构造函数

do_qemu_init_ ## function 使用了预处理连接符## 将function连接到do_qemu_init_ ,形成新的函数名,比如上面的type_init(register_accel_types) 最终会变成do_qemu_init_register_accel_types

这里就相当于模板函数接口

往下继续追踪register_module_init

void register_module_init(void (*fn)(void), module_init_type type)
{
    ModuleEntry *e;
    ModuleTypeList *l;

    e = g_malloc0(sizeof(*e));
    e->init = fn; // callback func
    e->type = type; // type

    l = find_type(type);

    QTAILQ_INSERT_TAIL(l, e, node);
}

这里的第二个参数type是个枚举类型

typedef enum {
    MODULE_INIT_MIGRATION,
    MODULE_INIT_BLOCK,
    MODULE_INIT_OPTS,
    MODULE_INIT_QOM,
    MODULE_INIT_TRACE,
    MODULE_INIT_XEN_BACKEND,
    MODULE_INIT_LIBQOS,
    MODULE_INIT_FUZZ_TARGET,
    MODULE_INIT_MAX
} module_init_type;