接前一篇文章: QEMU源码全解析 —— 块设备虚拟化(11)
本文内容参考:
《 QEMU /KVM源码解析与应用》 —— 李强,机械工业出版社
特此致谢!
QEMU初始化阶段的块设备虚拟化
从模板生成类和类的实例化
本回继续解析QEMU类Java反射机制的整个流程。上一回讲完了流程的第1步:
与之对应的QEMU中的步骤是:
type_init函数用于注册类。每一层都有class_init,用于从TypeImpl生产xxxClass。
接下来是与上述Java反射流程相对应流程的第2步:
以virtio_blk_info为例,virtio_blk_info中的class_init指向的函数为virtio_blk_class_init()。其在hw/block/virtio-blk.c中,代码如下:
static void virtio_blk_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
device_class_set_props(dc, virtio_blk_properties);
dc->vmsd = &vmstate_virtio_blk;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->realize = virtio_blk_device_realize;
vdc->unrealize = virtio_blk_device_unrealize;
vdc->get_config = virtio_blk_update_config;
vdc->set_config = virtio_blk_set_config;
vdc->get_features = virtio_blk_get_features;
vdc->set_status = virtio_blk_set_status;
vdc->reset = virtio_blk_reset;
vdc->save = virtio_blk_save_device;
vdc->load = virtio_blk_load_device;
vdc->start_ioeventfd = virtio_blk_data_plane_start;
vdc->stop_ioeventfd = virtio_blk_data_plane_stop;
}
前文已讲过,virtio_blk_class_init函数中会生成:
typedef struct DeviceState DeviceState;
typedef struct DeviceClass DeviceClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(DeviceState, object_unref)
static inline G_GNUC_UNUSED DeviceState *DEVICE(const void *obj)
{
return OBJECT_CHECK(DeviceState, obj, "device");
}
static inline G_GNUC_UNUSED DeviceClass *DEVICE_GET_CLASS(const void *obj)
{
return OBJECT_GET_CLASS(DeviceClass, obj, "device");
}
static inline G_GNUC_UNUSED DeviceClass *DEVICE_CLASS(const void *klass)
{
return OBJECT_CLASS_CHECK(DeviceClass, klass, "device");
}
和
typedef struct VirtIODevice VirtIODevice;
typedef struct VirtioDeviceClass VirtioDeviceClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(VirtIODevice, object_unref)
static inline G_GNUC_UNUSED VirtIODevice *VIRTIO_DEVICE(const void *obj)
{
return OBJECT_CHECK(VirtIODevice, obj, "virtio-device");
}
static inline G_GNUC_UNUSED VirtioDeviceClass *VIRTIO_DEVICE_GET_CLASS(const void *obj)
{
return OBJECT_GET_CLASS(VirtioDeviceClass, obj, "virtio-device");
}
static inline G_GNUC_UNUSED VirtioDeviceClass *VIRTIO_DEVICE_CLASS(const void *klass)
{
return OBJECT_CLASS_CHECK(VirtioDeviceClass, klass, "virtio-device");
}
也就是生成了struct DeviceClass和struct VirtioDeviceClass。
接下来是与上述Java反射流程相对应流程的第3步:
仍以virtio_blk_info为例,virtio_blk_info中的instance_init指向的函数为virtio_blk_instance_init。该函数也在hw/block/virtio-blk.c中,代码如下:
static void virtio_blk_instance_init(Object *obj)
{
VirtIOBlock *s = VIRTIO_BLK(obj);
device_add_bootindex_property(obj, &s->conf.conf.bootindex,
"bootindex", "/disk@0,0",
DEVICE(obj));
}
至此,QEMU中类Java反射机制的全部流程就全部讲解完了。