1. Virtio框架概述
Virtio是虚拟化环境中一种标准化的I/O设备框架,它为虚拟机提供了高效、统一的设备访问接口。在虚拟化场景中,Guest OS需要与Hypervisor进行通信以完成各种I/O操作,Virtio正是为此而设计的抽象层。
1.1 Virtio架构组成
从代码架构角度看,Virtio框架主要包含以下几个关键部分:
- 前端驱动(Frontend Driver):运行在Guest OS内核中,为上层应用提供标准设备接口
- 后端驱动(Backend Driver):运行在Hypervisor中,处理实际的硬件操作
- 通信层:包括两个关键抽象层:
- Virtio层:定义虚拟队列接口,连接前后端驱动
- Virtio-ring层:实现具体的环形缓冲区通信机制
1.2 虚拟队列机制
虚拟队列(Virtual Queue)是Virtio的核心通信机制,它具有以下特点:
- 每个设备可以根据需要使用一个或多个队列
- 队列通过环形缓冲区(ring buffer)实现
- 队列数量取决于设备类型:
- 网络设备:通常使用2个队列(接收和发送)
- 块设备:通常使用1个队列
- 控制台设备:使用1个队列
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Virtio PCI设备实现
2.1 PCI设备注册
Virtio PCI设备的注册过程主要涉及以下几个关键步骤:
- PCI设备探测:通过PCI设备ID匹配virtio设备
- 设备初始化:分配virtio_pci_device结构体
- 模式选择:根据配置选择传统模式或现代模式
- 设备注册:最终调用register_virtio_device完成注册
c复制static int virtio_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
struct virtio_pci_device *vp_dev;
int rc;
/* 分配设备结构体 */
vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL);
/* 初始化基础字段 */
pci_set_drvdata(pci_dev, vp_dev);
vp_dev->vdev.dev.parent = &pci_dev->dev;
vp_dev->pci_dev = pci_dev;
/* 启用PCI设备 */
rc = pci_enable_device(pci_dev);
/* 根据配置选择传统或现代模式 */
if (force_legacy) {
rc = virtio_pci_legacy_probe(vp_dev);
if (rc == -ENODEV || rc == -ENOMEM)
rc = virtio_pci_modern_probe(vp_dev);
} else {
rc = virtio_pci_modern_probe(vp_dev);
if (rc == -ENODEV)
rc = virtio_pci_legacy_probe(vp_dev);
}
/* 注册virtio设备 */
rc = register_virtio_device(&vp_dev->vdev);
return rc;
}
2.2 现代模式探测
现代模式(Modern Mode)是Virtio 1.0规范引入的新模式,相比传统模式有更好的性能和扩展性。其探测过程主要包括:
- 设备ID验证:检查设备是否在现代模式范围内(0x1040-0x107f)
- 能力查找:查找各种配置空间能力
- 内存映射:映射各种配置区域
- 操作设置:设置virtio_config_ops
c复制int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
{
struct virtio_pci_modern_device *mdev = &vp_dev->mdev;
struct pci_dev *pci_dev = vp_dev->pci_dev;
int err, common, isr, notify, device;
/* 检查设备ID范围 */
if (pci_dev->device < 0x1000 || pci_dev->device > 0x107f)
return -ENODEV;
/* 设置设备ID */
if (pci_dev->device < 0x1040) {
mdev->id.device = pci_dev->subsystem_device;
} else {
mdev->id.device = pci_dev->device - 0x1040;
}
/* 查找各种能力 */
common = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_COMMON_CFG,
I
