一,前言
开始qemu源码学习之路。从简书切换到此,真的是一键导入,太快了。
二,从某个点开始分析源码
Type_new函数就是把TypeInfo内容复制到TypeImpl。
1.总的来说type_register_internal就是创建一个TypeImpl类,然后添加到hash表中。
static TypeImpl *type_register_internal(const TypeInfo *info)
{
TypeImpl *ti;
ti = type_new(info);
type_table_add(ti);
return ti;
}
2.可以看到ti->name为key,ti为value.
static void type_table_add(TypeImpl *ti)
{
assert(!enumerating_types);
g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
}
3.关于父类继承是通过parent_type进行的连接。type_get_by_name通过hash表的name找到TypeImpl,然后子类指向父类的TypeImpl,其实是在type_initialize函数中处理的type_get_parent。
static TypeImpl *type_get_parent(TypeImpl *type)
{
if (!type->parent_type && type->parent) {
type->parent_type = type_get_by_name(type->parent);
g_assert(type->parent_type != NULL);
}
return type->parent_type;
}
这样来看,在代码中,其实就是通过name进行了父类关系连接。
4.type_initialize是一个关键函数,利用了归递方式,这是类似图形HMI编程常用的方法,比如litegul和LVGL都有类似的归递代码来处理图层,从底层绘制到顶层。当前qemu中是从父类开始,先复制父类的class到子类,然后一次进行type实例中class的初始化。
5.type_initialize还将Objectclass和TypeImpl进行了挂钩。
ti->class->type = ti;
6. MachineClass *mc = MACHINE_CLASS(oc);我理解直接指向class等于直接引用。
7. stm32f4_discovery_board_class_init_callback函数的关键路径。
居然是find_default_mechine后进行foreach循环处理之前添加到hash表的TypeImpl对象,然后进行归递初始化mc。
8. mc这个临时变量有什么用,居然赋值了init函数名字,那么我就在这个函数内打断点。
看上去来源是machine_class
9. 在select_machine函数中,也就是qemu启动传入的参数里面包括board名字,然后就找到了machine_class.
MachineClass *mc = find_machine(board_name);
if (mc == NULL) {
cm_board_help_func("?");
} else {
machine_class = mc;
}
刚刚说的mc临时参数,原来是find_machine的返回值,而且还给了变量machine_class,所以找到了关系。只是里面用了g_hash_table_foreach等api,不熟悉,仅猜测功能。
三,小结
这次主要是了解了TypeImpl的功能及2个初始化的路径。还发现了glib库函数,虽然看名字就猜到功能,百度一下也能知道的更清晰,但是这次是学习源码,所以glib库我不能停留在看的阶段,需要动手练习下,放入下一轮吧~