面向对象的设备模型

书接上回,说到device设备在设置了realized属性后会调用DeviceClass的realize函数进行初始化。那这个函数究竟是什么的?

要说清楚这件事,还得找一个具体的设备来说才能够看得清。

qemu中的函数重载

DeviceClass类型中的realize成员在device_class_init()初始化函数中并没有被设置。这个函数的具体对应是在DeviceClass的子类型的类型初始化函数中设置的。

比如PCIDeviceClass就是DeviceClass的一个子类型。在它的类型初始化函数pci_device_class_init中可以看到下面这段代码:

  k->realize = pci_qdev_realize;

所以在qemu的设备模型中其实采用了面向对象的编程方法。

面向对象的设备模型

讲了这么多,恐怕大家也听晕了。正所谓耳听为虚,眼见为实。我们来画一个图,看看e1000这个设备面向对象模型的样子。

       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   ObjectClass            | <-------------------------|    Object            |
       |     class_init           |                           |    instance_init     |
       |                          |                           |(object_instance_init)|
       +--------------------------+                           +----------------------+
                 |                                                      |
                 |                                                      |
                 |                                                      |
                 v                                                      v
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   DeviceClass            |  <---------------------   |   DeviceState        |
       |     class_init           |                           |      instance_init   |
       |     (device_class_init)  |                           |      (device_initfn) |
       |                          |                           |                      |
       |     realize              |  overwrite by child class |                      |
       |     unrealize            |                           |                      |
       +--------------------------+                           +----------------------+
                 |                                                      |
                 |                                                      |
                 |                                                      |
                 v                                                      v
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   PCIDeviceClass         |  <---------------------   |   PCIDevice          |
       |     class_init           |                           |      instance_init   |
       |   (pci_device_class_init)|                           |      (NULL)          |
       |     realize              |                           |                      |
       |     (pci_qdev_realize)   |  call PCIDevice->realize  |                      |
       |     unrealize            |                           |                      |
       |     (pci_qdev_unrealize) |                           |                      |
       +--------------------------+                           +----------------------+
                 |                                                      |
                 |                                                      |
                 |                                                      |
                 v                                                      v
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   E1000BaseClass         |  <--------------------    |   E1000State         |
       |     class_init           |                           |      instance_init   |
       |     (e1000_class_init)   |                           | (e1000_instance_init)|
       |     realize              |                           |                      |
       |     (pci_e1000_realize)  |                           |                      |
       |     unrealize            |                           |                      |
       |                          |                           |                      |
       +--------------------------+                           +----------------------+

在这张图中体现了这么几点:

  • 某个类型可以是另一个类型的子类型

  • 某个设备实例包含了父类型的实例

  • 实例和类型之间一一对应

  • 类型的成员可以被子类重写

到这里,感觉终于可以说对qemu的设备模型有了那么一点点的了解。

Last updated