基于qemu-7.1.0
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;