Full Analysis of QEMU Source Code 18 - Introduction to QOM (7)

Continued from the previous article: Full Analysis of QEMU Source Code 17 - Introduction to QOM (6)

References for the content of this article:

"Interesting Talk about Linux Operating System " —— Liu Chao, Geek Time

" QEMU /KVM" source code analysis and application - Li Qiang, Machinery Industry Press

Thank you very much!

Last time, I completed the explanation of the second part of QOM - type initialization. Continue to explain this time.

As mentioned earlier, the entire operation of QOM includes three parts: type registration, type initialization, and object initialization. But here we need to add a part - the hierarchical structure of types (this is a bit like the three knots of peach blossoms, followed by the fourth brother - Zhao Yun and Zhao Zilong).

From the type_initilize function mentioned last time, we can see that the parent type is initialized when the type is initialized, so it is necessary to introduce the hierarchical structure of the type. QOM realizes inheritance in object-oriented languages ​​such as C++ through this hierarchical structure. concept.

Still take the edu device mentioned above as an example. In order to facilitate understanding and deepen the impression, the code related to edu equipment is posted again. In hw/misc/edu.c:

static void pci_edu_register_types(void)
{
    static InterfaceInfo interfaces[] = {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    };
    static const TypeInfo edu_info = {
        .name          = TYPE_PCI_EDU_DEVICE,
        .parent        = TYPE_PCI_DEVICE,
        .instance_size = sizeof(EduState),
        .instance_init = edu_instance_init,
        .class_init    = edu_class_init,
        .interfaces = interfaces,
    };

    type_register_static(&edu_info);
}
type_init(pci_edu_register_types)

There is a parent member in the type information edu_info structure of the edu device, which specifies the name of the parent type of edu_info. The parent type of the edu device is TYPE_PCI_DEVICE, indicating that the edu device is designed as a PCI device. TYPE_PCI_DEVICE is defined in include/hw/pci/pci.h, as follows:

#define TYPE_PCI_DEVICE "pci-device"

The type information of TYPE_PCI_DEVICE is in hw/pci/pci.c, the code is as follows:

static const TypeInfo pci_device_type_info = {
    .name = TYPE_PCI_DEVICE,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(PCIDevice),
    .abstract = true,
    .class_size = sizeof(PCIDeviceClass),
    .class_init = pci_device_class_init,
    .class_base_init = pci_device_class_base_init,
};

Its parent type (for the edu device type TYPE_PCI_EDU_DEVICE is the master type) is TYPE_DEVICE, which is defined in include/hw/qdev-core.h, as follows:

#define TYPE_DEVICE "device"

The type information of TYPE_DEVICE is in hw/core/qdev.c, the code is as follows:

static const TypeInfo device_type_info = {
    .name = TYPE_DEVICE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DeviceState),
    .instance_init = device_initfn,
    .instance_post_init = device_post_init,
    .instance_finalize = device_finalize,
    .class_base_init = device_class_base_init,
    .class_init = device_class_init,
    .abstract = true,
    .class_size = sizeof(DeviceClass),
    .interfaces = (InterfaceInfo[]) {
        { TYPE_VMSTATE_IF },
        { TYPE_RESETTABLE_INTERFACE },
        { }
    }
};

Tracing back to the source, the parent type of TYPE_DEVICE (the great-grandfather type for the edu device type TYPE_PCI_EDU_DEVICE) is TYPE_OBJECT, which is defined in include/qom/object.h, as follows:

#define TYPE_OBJECT "object"

The type information of TYPE_OBJECT is in qom/object.c (turned back to the object.c file), the code is as follows:

static const TypeInfo object_info = {
    .name = TYPE_OBJECT,
    .instance_size = sizeof(Object),
    .class_init = object_class_init,
    .abstract = true,
};

TYPE_OBJECT has no parent class, which means that it is the end of TYPE_OBJECT, and it is the ultimate ancestor of all instances that can be initialized.

To review, the hierarchical relationship of the edu type is:

TYPE_PCI_EDU_DEVICE -> TYPE_PCI_DEVICE -> TYPE_DEVICE -> TYPE_OBJECT

Here, I can't help but think of the list of gods. Erlang God Yang Jian's master is Yuding Zhenren, Yuding Zhenren's master is Yuanshi Tianzun, and Yuanshi Tianzun's master is Hongjun Patriarch. It’s the end of Hongjun’s ancestor in the list of gods. Whether it’s cutting off religion, elucidating religion, or Taoism, good or bad are all disciples and grandchildren of ancestor Hongjun (of course, the list of gods can go further, the two leaders of Western religion It does not belong to the branch of Patriarch Hongjun, but the branch of Daoist Hun Kun, that is to say, the real root is Hongjun and Hun Kun's master who founded Yuan Ling). Speaking of virtualization, I was stunned to say that "Feng Shen Bang" is coming, come back, come back.

Similar to device, the ancestor of all interfaces is TYPE_INTERFACE, which is defined in include/qom/object.h, as follows:

#define TYPE_INTERFACE "interface"

The type information of TYPE_INTERFACE is also in qom/object.c (just above TYPE_OBJECT), the code is as follows:

static const TypeInfo interface_info = {
    .name = TYPE_INTERFACE,
    .class_size = sizeof(InterfaceClass),
    .abstract = true,
};

Still have to go back to "Fengshen Bang", this TYPE_INTERFACE is equivalent to that of the Western religion. In other words, in theory, TYPE_OBJECT and TYPE_INTERFACE should have a common father, that is, the father of classes and interfaces. I think it should be the system. However, there is no further pursuit in QEMU.

If you want to know what happened next, let's see the next chapter.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/132011334