数据流方向:virtio前端驱动 -> virtio -> transport(virtio-ring) -> virtio后端驱动
virtio前端驱动:
- 运行在虚拟机中
- 针对不同类型的设备有不同的驱动程序,但是与后端驱动交互的接口都是统一的
- virtio_net模块,源码位于 drivers/net/virtio_net.c
- virtio_blk,virtio_net,virtio_pci,virtio_ballon,virtio_scsi
virtio层:
- virtio层实现虚拟队列接口,作为前后端通信的桥梁
- 不同类型的设备使用的虚拟队列数量不同,比如virtio_net使用两个队列,一个用于接收,另一个用于发送
- 源码位于 drivers/virtio/virtio.c
virtio-ring层:
- virtio-ring层是虚拟队列的具体实现
- 源码位于 driver/virtio/virtio_ring.c
virtio后端驱动
- 运行在宿主机
- 实现virtio后端的逻辑,主要是操作硬件设备,比如向内核协议栈发送一个网络包完成虚拟机对于网络的操作。
- 在Qemu+KVM虚拟化环境中,virtio后端驱动的代码位于Qemu源码中。
虚拟机中运行的virtio驱动前端是否需要手动安装
并非所有操作系统都默认支持VirtIO设备。例如,Windows操作系统不自带对VirtIO设备的支持,因此必须手动安装对应的驱动程序。
windows虚拟机安装virtio前端驱动的步骤:
- 添加临时VirtIO设备:为了能够从VirtIO驱动ISO中安装驱动程序,你可能需要先向虚拟机添加一个临时的VirtIO设备(比如一个空的VirtIO SCSI控制器)。这允许你在没有完全切换到VirtIO之前就能够访问驱动程序。
- 加载VirtIO ISO:下载最新的VirtIO驱动ISO并将它作为CD-ROM挂载到虚拟机中。
- 安装驱动程序:进入Windows后,在设备管理器中找到未识别或带有黄色感叹号的设备(前面添加的临时VirtIO设备),然后选择更新驱动程序软件,并指向VirtIO ISO所在的虚拟光驱进行安装。
- 重启虚拟机:完成驱动安装后,关闭虚拟机,并将虚拟硬盘重新配置为使用VirtIO SCSI控制器而不是SATA控制器,之后再次启动虚拟机以验证是否正确识别了新的控制器。
linux虚拟机通常自带了virtio前端驱动,确认virtio驱动是否加载的方法:
lsmod | grep virtio
:如果输出结果中有类似virtio_net, virtio_blk, 或者其他的VirtIO模块,那么说明这些驱动已经被加载并正在使用。- 检查初始化RAM磁盘(initrd): 有时即使内核支持VirtIO设备,但如果初始化RAM磁盘(initrd)没有包含必要的模块,系统在启动时可能无法正确识别这些设备。
- 编辑/etc/sysconfig/kernel文件,并添加或确保以下行存在:
INITRD_MODULES="virtio_blk virtio_net"
- 然后重建initrd镜像:
dracut -f
- 编辑/etc/sysconfig/kernel文件,并添加或确保以下行存在:
virtio后端
virtio后端代码位于QEMU源码中(如hw/virtio/目录),负责模拟PCI设备(如virtio-net、virtio-blk),并通过vring与客户机前端驱动交互。
工作流程:
- 初始化:
- PCI设备探测时,QEMU注册virtio设备(如virtio_blk_init_pci),初始化vring和回调函数
- 客户机启动后,前后端通过特性协商(feature bits)确定支持的功能
- 请求处理:
- 前端驱动将I/O请求描述符写入vring的Available Ring,并通知后端(通过I/O端口或MMIO)
- 后端从vring读取请求,解析VirtQueueElement结构,映射客户机物理地址到宿主机虚拟地址,执行实际I/O(如写文件、发送网络包)
- 完成操作后,后端将结果写入Used Ring,并注入中断通知前端
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。