KVM+QEMU世界中的pci总线与virtio总线

本文深入解析了在虚拟化环境中,如何通过配置GuestOS内的Linux内核来支持9P文件系统在Host OS与Guest OS间的共享。重点讨论了PCI总线与Virtio总线之间的技术细节,特别是在使用QEMU命令行启动虚拟机时,如何通过参数选项在Guest OS中创建对应的PCI和Virtio设备。文章详细解释了设备如何在PCI和Virtio总线下被发现、加载驱动,并最终在Guest OS中呈现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章的背景是通过9p文件系统在host os与guest os间共享一个目录,或许更专业点的叫法是File system Passthru. 因此需要配置guest os中Linux内核,使之支持下面的选项(.config)

CONFIG_NET_9P=y

CONFIG_NET_9P_VIRTIO=m

CONFIG_9P_FS=y

CONFIG_9P_FS_POSIX_ACL=y

但是本文不讨论如何使用9P文件系统来达成这一目标的具体步骤 ,而是讨论其幕后实现中 的一个技术细节:pci总线与virtio总线的关系。

在上述的背景下, 如果我们使用QEMU命令行来启动一个VM,在命令行中加入类似: -device virtio-9p-pci 这样的参数选项时, 那么在Guest OS中不但在/sys/bus/pci/devices中出现一个对应的pci设备,而且在/sys/bus/virtio/devices中也会出现一个virtio类型设备。


我们知道PCI总线是现代计算机体系结构中普遍存在的一个物理总线,而virtio总线则纯粹是软件定义的,在KVM+QEMU的世界里,两者之间到底是何关系?或者假设我们现在想在QEMU+KVM中添加一个新的virtio设备及其驱动,应该怎么做?

 

通常,Guest OS在初始化过程中会扫描pci bus num = 0的host bridge,也就是北桥,通过它来发现其下挂载的一系列pci设备(包括桥设备),所以我们想添加的的新的virtio设备必须对外展现出一个pci的接口。因为host bridge本身就是靠QEMU模拟出来的,所以在QEMU中模拟一个新的pci设备也是很简单的事情。如果QEMU成功模拟了一个挂在host bridge上的pci设备,那么Guest OS将会通过PCI总线扫描发现之,继而通过device_add函数把该设备添加到系统中,这将导致:
1. 在Guest OS中的/sys/bus/pci/devices目录下出现一个新的pci设备(被QEMU模拟出的)  
2. 在Guest OS中与该pci设备对应的驱动程序将会被加载(围绕着PCI总线的bind)。

 

到目前为止,都是PCI的作用范围,跟virtio总线没有什么关系。那么Guest OS中/sys/bus/virtio/devices下面出现的设备及其驱动又是如何产生的?

 

答案是pci设备驱动中定义的virtio_pci_probe().  在drivers/virtio/virtio_pci.c中:

 

/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */

static DEFINE_PCI_DEVICE_TABLE(virtio_pci_id_table) = {

{ PCI_DEVICE(0x1af4, PCI_ANY_ID) },

{ 0 }

};

 

MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);

 

static struct pci_driver virtio_pci_driver = {

.name                = "virtio-pci",

.id_table        = virtio_pci_id_table,

.probe                = virtio_pci_probe,

.remove        = virtio_pci_remove,

#ifdef CONFIG_PM_SLEEP

.driver.pm        = &virtio_pci_pm_ops,

#endif

};

 

virtio-pci的vendor ID是0x1af4, 这个是当初开发KVM的Qumranet公司PCI Vendor ID。所以,如果在QEMU侧模拟一个pci设备,其vendor ID=0x1af4,那么当Guest OS扫描到该设备时,将会将其加入到系统,于是使得上述的virtio_pci_driver被加载,该过程导致在/sys/bus/pci/devices中出现一个vendor id = 0x1af4的pci设备,同时该设备指向一个名为"virtio-pci"的驱动程序。这期间很重要的一个环节是"virtio-pci"驱动中的.probe成员,也即virtio_pci_probe().

 

在virtio_pci_probe()函数中,它将调用register_virtio_device(),后者将把一个virtio类型(struct  virtio_device)的设备加入到系统,由于该设备所属的总线是virtio bus(源码在drivers/virtio/virtio.c), 导致/sys/bus/virtio/devices/目录下出现一个新的设备:

int register_virtio_device(struct virtio_device *dev)

{

dev->dev.bus = &virtio_bus;

}

 

所以围绕virtio bus导致该设备的驱动被加载。(以上的过程很类似一个PCI接口的FC HBA卡的驱动模式:先PCI总线,后SCSI总线).这个virtio_device的设备驱动定义在net/9p/trans_virtio.c中。

因为OS启动过程中会扫描pci总线,所以必要使得一个设备先能被系统识别(基于pci),然后再做下一步的处理(基于scsi或者virtio...)。更形象地说,一个披着羊皮的狼才能被羊群所接纳,然后再脱掉羊皮变成狼,显现狼的行为。

<think>好的,用户想要在KVM中配置QEMU使用Q35芯片组的信息或指南。我需要先回忆一下Q35的相关知识,以及如何在QEMU中使用它。首先,根据引用[2],Q35是QEMU的最新机型,基于ICH9芯片组,推荐用于KVM虚拟机。它支持PCIe、AHCI控制器等,这对NVMe设备很重要。用户可能需要知道如何创建Q35虚拟机的基本命令。然后,引用[1]提到Q35的machine选项是通过别名关联的,比如使用-Mq35参数。所以,在启动虚拟机时,指定-M q35应该就是关键步骤。例如,qemu-system-x86_64 -Mq35...这样的命令。引用[3]中的命令行示例显示-machine参数的使用,比如-machinepc-i440fx-trusty,但用户需要的是Q35,所以应该是类似-machineq35的选项。不过具体的机器类型可能有版本号后缀,如pc-q35-4.1,但用户可能更倾向于使用别名q35,这样更简单。接下来,用户可能需要知道如何验证是否成功配置了Q35。可以通过在QEMU monitor中使用info qtree命令,或者检查PCI总线是否为PCIe。另外,关于配置文件的位置,比如libvirt的XML配置,用户如果使用libvirt管理虚拟机,可能需要编辑domain的<machine>部分为pc-q35-*的格式,并确保芯片组设置为ich9。还有可能需要注意的优化点,比如启用AHCI控制器来支持SATA设备,或者添加PCIe设备。例如,使用-device ahci,id=ahci来启用AHCI,以及使用NVMe磁盘时需要指定驱动为nvme。用户可能遇到的问题包括如何确认当前使用的芯片组,或者旧版兼容性问题。例如,某些旧的客户机系统可能不完全支持Q35,需要检查兼容性。最后,生成相关问题时要考虑用户可能的后续疑问,比如性能优化、i440fx的区别,或者具体设备配置方法。</think>### KVM中配置QEMU使用Q35芯片组指南 #### 一、基础配置方法 1. **命令行启动参数** 使用`-M q35`或`-machine q35`参数直接指定芯片组: ```bash qemu-system-x86_64 -M q35 -m 4G -boot d -cdrom ubuntu.iso ``` 该参数会调用Q35的默认配置`pc-q35-*`(具体版本号由QEMU决定)[^1][^2]。 2. **验证Q35配置** 在QEMU monitor中执行: ```bash info qtree ``` 若看到`ich9-ehci1-uhci1-6`等ICH9设备,则表明Q35生效[^2]。 #### 二、Libvirt虚拟机配置 1. **XML定义修改** 在`<domain>`标签内指定机器类型: ```xml <os> <type arch='x86_64' machine='pc-q35-6.2'>hvm</type> </os> <features> <acpi/> <apic/> </features> ``` 需根据QEMU版本调整`machine`字段的版本号后缀[^1][^3]。 2. **芯片组参数扩展** 启用ICH9的完整功能: ```xml <devices> <controller type='pci' model='pcie-root'/> <controller type='sata' index='0' model='ich9-ahci'/> </devices> ``` #### 三、关键设备配置 1. **AHCI控制器** 需显式声明SATA控制器: ```bash -device ahci,id=ahci ``` 存储设备应挂载到该控制器: ```bash -drive file=disk.img,if=none,id=sata0 -device ide-hd,bus=ahci.0,drive=sata0 ``` 2. **PCIe设备支持** GPU直通等场景需指定PCIe插槽: ```bash -device vfio-pci,host=01:00.0,bus=pcie.0,addr=0x1 ``` #### 四、兼容性注意事项 1. **旧系统支持** Windows 7等系统需额外加载`virtio-win`驱动,否则可能无法识别virtio存储设备。 2. **固件选择** 推荐使用UEFI启动: ```bash -bios /usr/share/OVMF/OVMF_CODE.fd ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值