2.客戶機PCI裝置進行枚舉和資源分派
當Linux客戶機系統啟動時,對PCI裝置進行枚舉和資源分派(配置PCI的配置空間),通常由BIOS完成。不過對Linux系統提供方式,一種由BIOS實現,另一種自己實現枚舉和資源分派功能。代碼位於kernel:arch/x86/pci/init.c
static __init int pci_arch_init(void)
{
#ifdef CONFIG_PCI_DIRECT
int type = 0;
return 0;
}
pcibios_scan_root()---->pci_scan_bus_parented()---->pci_scan_child_bus()--->pci_scan_slot()--->pci_scan_single_device()----->pci_device_add()
將PCI匯流排上的裝置添加到鏈表
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
{
/*
* Add the device to our list of discovered devices
* and the bus list for fixup functions, etc.
*/
down_write(&pci_bus_sem);
list_add_tail(&dev->bus_list, &bus->devices);
up_write(&pci_bus_sem);
}
上述過程執行完成,在/sys/devices/pci0000:00目錄下,建立virtio pci裝置。並且在/sys/bus/pci/devices/目錄下,建立相應對於pci裝置的符號串連,同時在/sys/bus/pci/drivers/目錄下,建立virtio-pci目錄,目錄下存在支援裝置符號串連檔案。
/* we use the subsystem vendor/device id as the virtio vendor/device
* id. this allows us to use the same PCI vendor/device id for all
* virtio devices and to identify the particular virtio driver by
* the subsytem ids */
vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor;
vp_dev->vdev.id.device = pci_dev->subsystem_device;
/* finally register the virtio device */
err = register_virtio_device(&vp_dev->vdev);
if (err)
goto out_set_drvdata;
/* We have a driver! */
add_status(dev, VIRTIO_CONFIG_S_DRIVER);
/* Figure out what features the device supports. */
device_features = dev->config->get_features(dev);
/* Features supported by both device and driver into dev->features. */
memset(dev->features, 0, sizeof(dev->features));
for (i = 0; i < drv->feature_table_size; i++) {
unsigned int f = drv->feature_table[i];
BUG_ON(f >= 32);
if (device_features & (1 << f))
set_bit(f, dev->features);
}
/* Transport features always preserved to pass to finalize_features. */
for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
if (device_features & (1 << i))
set_bit(i, dev->features);