接前一篇文章: QEMU源码全解析9 —— 定义一个QEMU模块(1)
本文内容参考:
《 QEMU /KVM》源码解析与应用 —— 李强,机械工业出版社
特此致谢!
上一回讲到定义一个 QEMU 模块会调用type_init,并以kvm作为例子,讲到了以下代码(在accel/kvm/kvm-all.c中):
type_init(kvm_type_init);
上一回是沿着type_init宏定义这一分支讲下去了,本回让我们回到“双阳岔道”,来走一下另一个分支——kvm_type_init即KVM这个module的初始化函数的具体实现。
kvm_type_init函数实际上就在type_init(kvm_type_init);这一行的上边,代码如下:
- static void kvm_type_init(void)
- {
- type_register_static(&kvm_accel_type);
- }
-
- type_init(kvm_type_init);
kvm_accel_type的初始化代码就在kvm_type_init的上边,如下所示:
- static const TypeInfo kvm_accel_type = {
- .name = TYPE_KVM_ACCEL,
- .parent = TYPE_ACCEL,
- .instance_init = kvm_accel_instance_init,
- .class_init = kvm_accel_class_init,
- .instance_size = sizeof(KVMState),
- };
kvm_type_init会注册kvm_accel_type。可以认为kvm_accel_type是动态定义了一个类,该类的名字是TYPE_KVM_ACCEL;其父类是TYPE_ACCEL;该类的初始化应调用函数kvm_accel_class_init;如果用此类声明一个对象,对象的大小为instance_size。
kvm_type_init函数会简单调用type_register_static函数,该函数在qom/object.c中,代码如下:
- TypeImpl *type_register_static(const TypeInfo *info)
- {
- return type_register(info);
- }
可见,type_register_static函数又是type_register函数的简单封装。type_register函数就在type_register_static函数的上边,代码如下:
- TypeImpl *type_register(const TypeInfo *info)
- {
- assert(info->parent);
- return type_register_internal(info);
- }
继续跟进,type_register_internal函数又在type_register函数的上边,代码如下:
- static TypeImpl *type_register_internal(const TypeInfo *info)
- {
- TypeImpl *ti;
- ti = type_new(info);
-
- type_table_add(ti);
- return ti;
- }
终于不再是简单封装函数了。type_register_internal函数中共有2个函数:type_new和type_table_add。
对于type_register_internal函数以及其中的2个函数的深入解析,我们放到下一篇文章。