设备类型初始化

一一对应

注册类型TypeImpl之后就需要初始化该类型,如果打开TypeImpl这个结构体,可以看到其中有个叫class的成员。初始化其实就是初始化的它。

    TypeImpl                               ObjectClass
    +----------------------+               +----------------------+
    |class                 |<------------->|type                  |
    |     (ObjectClass*)   |               |     (TypeImpl *)     |
    +----------------------+               +----------------------+

进行初始化的具体函数是 type_initialize()。

摘取其中主要的流程如下:

  type_initialize()
    ...
    parent = type_get_parent(ti);
    if (parent) {
      type_initialize(parent);
      ...
      for (i = 0; i < ti->num_interfaces; i++) {
        TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
        ...
        type_initialize_interface(ti, t, t);
      }
    }

    ...

    while (parent) {
      if (parent->class_base_init) {
        parent->class_base_init(ti->class, ti->class_data);
      }
      parent = type_get_parent(parent);
    }

    if (ti->class_init) {
      ti->class_init(ti->class, ti->class_data);
    }

其中主要做了几件事:

  • 设置类型的大小并创建该类型

  • 设置类型实例的大小,为实例化设备做准备

  • 初始化父设备类型,如果没有的话

  • 初始化接口类型

  • 调用父设备类型的class_base_init初始化自己

  • 调用class_init初始化自己

在这里看不出什么具体的东西,因为每种设备类型将执行不同的初始化函数。

但是有一点可以看出的是,qemu设备类型有一个树形结构。或者说是一种面向对象的编程模型,需要初始化父类后,再初始化自己。

接口类

在看了一段时间代码后,发现一个类型还能定义其相关的接口类型。

比如我们看e1000设备的定义可以看到在最后有定义一个interfaces成员。

那么我们来看看这个成员如何初始化,如何使用。

在 type_initialize()函数中有一段

这个就是在初始化ti这个类型的接口类。好在这个函数type_initialize_interface()不长,我们直接打开看看。

说实话,这个东西有点绕。因为在这个过程中又注册了一个新的类型并做了初始化。

最后的结果我尝试用图来展示。

  • 创建了一个INTERFACE_CONVENTIONAL_PCI_DEVICE类型的子类,也是一个接口类型

  • E1000BaseClass中的interfaces会指向新建的接口类

  • 而接口类中的concrete_class会指向E1000BaseClass

Last updated

Was this helpful?