接前一篇文章:
本文内容参考:
《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社
特此致谢!
上两回对于virtio进行了简介,并说明了其基本原理以及框架。本回开始正式结合代码讲解virtio的实现机制和细节。
virtio设备的初始化
virtio设备首先需要创建一个PCI设备,叫作virtio PCI代理设备,这个代理设备挂到PCI总线上。
接着,virtio代理设备再创建一条virtio总线,这样virtio设备就可以挂到这条virtio总线上了。
首先来看virtio PCI代理设备类型的定义,在QEMU源码(qemu-8.1.3)的hw/virtio/virtio-pci.c中,代码如下:
static const TypeInfo virtio_pci_bus_info = {
.name = TYPE_VIRTIO_PCI_BUS,
.parent = TYPE_VIRTIO_BUS,
.instance_size = sizeof(VirtioPCIBusState),
.class_size = sizeof(VirtioPCIBusClass),
.class_init = virtio_pci_bus_class_init,
};
static void virtio_pci_register_types(void)
{
/* Base types: */
type_register_static(&virtio_pci_bus_info);
type_register_static(&virtio_pci_info);
}
type_init(virtio_pci_register_types)
从virtio PCI代理设备的定义就可以看出,virtio PCI代理设备的父设备是一个PCI设备(.parent = TYPE_PCI_DEVICE,),类型为VirtIOPCIClass(.class_size = sizeof(VirtioPCIClass),),实例为virtIOPCIProxy(.instance_size = sizeof(VirtIOPCIProxy),),注意这是一个抽象设备(.abstract = true,),因此并不能创建其实例,只能由其子类去创建。
QEMU中定义了所有virtio设备的PCI代理设备,如virtio balloon PCI设备、virtio scsi PCI设备、virtio crypto PCI设备。其定义分别如下所示:
- virtio balloon PCI设备
virtio balloon PCI设备的定义在hw/virtio/virtio-balloon-pci.c中,代码如下:
static const VirtioPCIDeviceTypeInfo virtio_balloon_pci_info = {
.base_name = TYPE_VIRTIO_BALLOON_PCI,
.generic_name = "virtio-balloon-pci",
.transitional_name = "virtio-balloon-pci-transitional",
.non_transitional_name = "virtio-balloon-pci-non-transitional",
.instance_size = sizeof(VirtIOBalloonPCI),
.instance_init = virtio_balloon_pci_instance_init,
.class_init = virtio_balloon_pci_class_init,
};
static void virtio_balloon_pci_register(void)
{
virtio_pci_types_register(&virtio_balloon_pci_info);
}
type_init(virtio_balloon_pci_register)
- virtio scsi PCI设备
virtio scsi PCI设备的定义在hw/virtio/virtio-scsi-pci.c中,代码如下:
static const VirtioPCIDeviceTypeInfo virtio_scsi_pci_info = {
.base_name = TYPE_VIRTIO_SCSI_PCI,
.generic_name = "virtio-scsi-pci",
.transitional_name = "virtio-scsi-pci-transitional",
.non_transitional_name = "virtio-scsi-pci-non-transitional",
.instance_size = sizeof(VirtIOSCSIPCI),
.instance_init = virtio_scsi_pci_instance_init,
.class_init = virtio_scsi_pci_class_init,
};
static void virtio_scsi_pci_register(void)
{
virtio_pci_types_register(&virtio_scsi_pci_info);
}
type_init(virtio_scsi_pci_register)
- virtio crypto PCI设备
virtio crypto PCI设备的定义在hw/virtio/virtio-crypto-pci.c中,代码如下:
static const VirtioPCIDeviceTypeInfo virtio_crypto_pci_info = {
.generic_name = TYPE_VIRTIO_CRYPTO_PCI,
.instance_size = sizeof(VirtIOCryptoPCI),
.instance_init = virtio_crypto_initfn,
.class_init = virtio_crypto_pci_class_init,
};
static void virtio_crypto_pci_register_types(void)
{
virtio_pci_types_register(&virtio_crypto_pci_info);
}
type_init(virtio_crypto_pci_register_types)
virtio设备在系统的设备树中的位置如下图所示:
欲知后事如何,请看下回分解。