QEMU源码分析-QOM
本文最后更新于:8 天前
QOM简介
QOM(QEMU Object Model)是QEMU的一个模块,用于描述虚拟机的结构,包括虚拟机的CPU、内存、硬盘、网络、输入输出设备等。QEMU 为了方便整个系统的构建,实现了自己的一套的面向对象机制,也就是QOM(QEMU Object Model)。
QOM中的面向对象
继承
在 QEMU 中通过 TypeInfo 来定义一个类。
例如 x86_base_cpu_type_info 就是一个 class,
1  |  | 
利用结构体包含来实现继承。这应该是所有的语言实现继承的方法,在 C++ 中,结构体包含的操作被语言内部实现了,而 C 语言需要自己实现。
例如 x86_cpu_type_info 的 parent 是 cpu_type_info, 他们的结构体分别是 X86CPU 和 CPUState。
1  |  | 
在 X86CPU 中包含一个 CPUState。
1  |  | 
静态成员
静态成员变量可以在类的多个对象中访问,但是要在类外声明。不同对象访问的其实是同一个实体,静态成员变量被多个对象共享。
1  |  | 
其中 X86CPU 描述的是非静态成员,而 X86CPUClass 描述的是静态的成员。也就是说class_init初始化静态成员,instance_init初始化非静态成员。
那么何时初始化静态成员呢?首先得告诉系统,咱有class_init这个初始化函数,等需要的时候随时可以调用它初始化,所有先解决如何将这个初始化函数注册到系统中?
在target/i386/cpu.c最后使用了type_init。在qemu/include/qemu/module.h中有一个type_init宏定义,除了type_init还有其他宏,比如block_init,opts_init等。每个宏都表示一类module,通过module_init构造出来。我们展开这个宏,
1  |  | 
通过 gcc 扩展属性__attribute__((constructor))可以让 do_qemu_init_x86_cpu_register_types 在运行 main 函数之前运行。 register_module_init 会让 x86_cpu_register_types 这个函数挂载到 init_type_list[MODULE_INIT_QOM] 这个链表上。
到底,所有的 TypeInfo 通过 type_init 都被放到 type_table 上了,之后通过 Typeinfo 的名称调用 type_table_lookup 获取到 TypeImpl 了。
到这里,将TYPE_X86_CPU注册进类系统,包括其初始化函数,这部分也就是QEMU中类型的构造。那么何时调用静态成员初始化函数呢?也就是类型的初始化。
静态成员是所有的对象公用的,其初始化显然要发生在所有的对象初始化之前。
1  |  | 
select_machine 需要获取所有的 TYPE_MACHINE 的 class, 其首先会调用所有的 class_list,其会遍历 type_table,遍历的过程中会顺带 type_initialize 所有的 TypeImpl 进而调用的 class_init。
说完类型的初始化,再讲一下对象的初始化,也就是初始化非静态成员,也就是instance_init在何时被调用?
对象初始化,通过调用 object_new 来实现初始化。
object_initialize_with_type- 初始化一个空的 :
Object::properties object_init_with_type- 如果 
object有parent,那么调用object_init_with_type首先初始化parent的 - 调用
TypeImpl::instance_init 
- 如果 
 
- 初始化一个空的 :
 
1  |  | 
动态类型装换(dynamic cast)
多态
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!
