设为首页 收藏本站
查看: 1314|回复: 0

[经验分享] struct kvm_io_device_ops struct virtio_device

[复制链接]

尚未签到

发表于 2015-10-10 10:26:26 | 显示全部楼层 |阅读模式
在 KVM 内核空间的 MMIO 和 PIO 实现比较简单, KVM 实现了一个抽象的 IO_BUS 模型,把所有的设备都按 struct kvm_io_device 抽象实现,要求每个都提供自己的 struct kvm_io_dev_ops 接口的实现, 每个平台设备的 struct kvm_io_dev_ops 的 read/write 函数的主要功能就是根据 IO 地址读写该设备内核数据结构的不同部分, 并根据数据的值变化实现一定的逻辑。
   
这篇文章的背景是通过9p文件系统在host os与guest os间共享一个目录,或许更专业点的叫法是Filesystem 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 这样的参数选项时, 那么在GuestOS中不但在/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的接口。因为hostbridge本身就是靠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,那么当GuestOS扫描到该设备时,将会将其加入到系统,于是使得上述的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...)。更形象地说,一个披着羊皮的狼才能被羊群所接纳,然后再脱掉羊皮变成狼,显现狼的行为。

         版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-124993-1-1.html 上篇帖子: KVM虚拟化原理与实践(连载) 下篇帖子: kernel hacker修炼之道之内核虚拟化 KVM/QEMU——Guest OS, Qemu
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表