Virtio 系列(一):框架概览

Virtual I/O Device (VIRTIO) Version 1.1

概述

这是一篇框架概览。图中的中间列表示 virtio 规范定义的 driver-device interface;左右两侧分别表示 Linux guest 侧和 VMM/device 侧如何实现这个接口。图中的箭头用于说明主要交互方向,不等同于源码中的函数调用顺序。

本文中的 VMM 指 Virtual Machine Monitor,即负责创建和运行虚拟机的软件层;在讨论 virtio 时,本文重点关注它实现 guest 可见设备和后端 I/O 的部分。

1. virtio 解决什么问题

  传统设备模拟让 guest 看到一块"真实硬件",例如 e1000 网卡、IDE 控制器或 UART。兼容性好,但寄存器语义复杂,虚拟化开销高。

  virtio 的目标是为虚拟化场景定义一套半虚拟化设备接口。guest 不再模拟操作复杂历史硬件,而是通过统一的 virtio 协议与 VMM 侧设备交换控制信息和数据 buffer。

  它的关键优势在于降低虚拟 I/O 的陷入成本。传统设备模拟往往围绕寄存器级行为展开,guest 的大量寄存器访问会触发 trap/VM-exit,由 VMM 逐次解释设备语义。virtio 则把高频数据路径放到共享内存 virtqueue 中:driver 批量提交 buffer 描述,device 批量取走并完成处理;VMM 通常只在配置访问、queue notify、interrupt 等事件点介入。换句话说,virtio 不是消除 VM-exit,而是显著减少"每次 I/O 都围绕寄存器模拟往返"的成本。

  因此,virtio 的价值不仅是性能优化,也包括接口标准化:同一套控制面、virtqueue 和事件通知机制可以承载 net、blk、console 等多种虚拟设备,并通过 feature bits 保持前后端兼容扩展。

  核心角色如下:

  • virtio driver:guest OS 中的前端驱动。
  • virtio device:VMM、host 或其他后端提供的虚拟设备。
  • transport:设备暴露和访问方式,例如 PCI、MMIO、CCW。
  • virtqueue:driver 与 device 交换 buffer 的共享队列机制。

  注意 :virtio 规范中的 driver/device 是协议角色,不完全等同于 Linux driver model 中的 struct device_driver / struct device

2. Guest / Driver Side

guest 侧主要由三类组件组成。

图中组件 职责 Linux 典型源码
Virtio Frontend Driver 实现具体设备语义,例如 net、blk、console drivers/net/virtio_net.cdrivers/block/virtio_blk.cdrivers/char/virtio_console.c
Linux Virtio Core virtio bus、driver/device 匹配、通用 setup 流程 drivers/virtio/virtio.cinclude/linux/virtio_config.h
Transport Driver 把 virtio core 的通用操作转换为 PCI/MMIO/CCW 访问 drivers/virtio/virtio_mmio.cdrivers/virtio/virtio_pci*

  图中的 Linux Virtio Core: virtio bus + virtio setup 需要区分两层含义:

  • virtio bus 是 Linux driver model 中的匹配机制,用于绑定 virtio_devicevirtio_driver
  • virtio setup 是 virtio 初始化流程,包括 feature negotiation、status 更新、config access、virtqueue 初始化等。

  二者不是同一级概念,但都属于 Linux virtio core 参与组织或封装的范围。

3. Virtio Interface

  中间列是 virtio 协议接口本身。它不是某个 .c 文件的归属划分,而是 driver 与 device 之间共同遵守的接口模型。

3.1 Control Interface

  控制接口承载低频控制信息:

  • device status
  • feature bits
  • device-specific config space
  • reset、config change 等控制语义

  feature negotiation 和 status state machine 是 virtio 初始化的核心。Linux 前端驱动声明支持的 feature;virtio core 组织协商;transport driver 完成底层寄存器或配置空间访问。

3.2 Virtqueue / vring

  virtqueue 是 virtio 的数据通道。它通过 descriptor、available ring、used ring 等共享内存结构,让 driver 和 device 交换 buffer 描述与完成信息。

  virtqueue 在 Linux 中不是单层独占:

  • frontend driver 提供业务 buffer/request;
  • virtio_ring.c 维护 vring 结构并实现 virtqueue API;
  • transport driver 负责 queue setup、notify、interrupt 等 transport-specific 细节;
  • VMM 侧 core/backend 负责取出 queue 中的请求并处理。

  具体的 descriptor table、avail ring、used ring、buffer ownership、notification suppression 等协议细节,适合放在后续文章中单独展开。

3.3 Event Signaling

  事件通道只负责通知,不承载数据:

  • driver notify device:guest 放入新 buffer 后通知 device;
  • device interrupt driver:device 完成处理后通知 guest。

  数据仍然通过 virtqueue 交换。notify 和 interrupt 只是提示对方"队列或配置状态可能发生变化"。

4. Device Side / VMM

  VMM 侧不是 Linux 前端驱动的镜像,而是虚拟设备的实现侧。

图中组件 含义 QEMU 典型源码
Transport Endpoint guest-visible 的 PCI/MMIO/CCW 入口 hw/virtio/virtio-mmio.chw/virtio/virtio-pci.c
VMM Virtio Core 通用 virtio 状态、feature、vqueue dispatch hw/virtio/virtio.cinclude/hw/virtio/virtio.h
Virtio Device Backend 具体设备模型,例如 net、blk、serial hw/net/virtio-net.chw/block/virtio-blk.chw/char/virtio-serial-bus.c
Host I/O Backend 具体 host 资源 TAP、image file、chardev、pty

  Transport Endpoint 运行在 VMM/host 侧,但它模拟的是 guest 可见的设备入口。guest 通过 PCI、MMIO 或 CCW 访问 virtio 设备;VMM 侧再把这些访问转换为通用 virtio 状态、队列分发和具体后端行为。

  因此,VMM 侧不能简单理解成"一个后端驱动"。它通常包含 guest 可见入口、通用 virtio core、具体设备模型,以及最终连接 host 资源的 I/O backend。

5. 小结

  virtio 不是某一个驱动,而是一套面向虚拟化 I/O 的 driver-device interface。它用共享内存 virtqueue 承载高频数据路径,用少量 notify/interrupt 事件同步状态,从而避免传统设备模拟中大量寄存器级 trap/VM-exit。

从框架图的视角看:

  • guest 侧由 frontend driver、Linux virtio core、transport driver 共同实现前端。
  • 中间的 control、virtqueue、event signaling 是 virtio 协议接口。
  • VMM 侧由 transport endpoint、virtio core、device backend、host I/O backend 共同实现后端。

  这种分层视角有助于区分 transport、core、queue、frontend 和 backend 的职责边界,也为后续阅读 Linux 与 VMM 侧源码建立统一坐标。。

  下一篇会继续深入 virtio 协议细节,例如 status state machine、feature negotiation、device config space、split/packed virtqueue、notification/interrupt、transport 差异等。

相关推荐
Yang_jie_032 小时前
笔记:数据结构(栈是否使用底指针以及头指针的初始化值)
数据结构·笔记·算法
小心亦新2 小时前
STM32学习12--串口2收发数据包
学习
Starmoon_dhw2 小时前
题解:P17078 夏日甜点
c++·学习·算法·图论
菩提树下的打坐3 小时前
接口测试利器:REST Assured + WireMock
学习
一杯奶茶¥3 小时前
c语言程序设计大学期末考试考研知识点重点笔记题库复习资料C语言重点考点题库资料合集
c语言·笔记·考研·c语言程序设计·c语言笔记
依然范特东3 小时前
动手学深度学习笔记--数据操作、线性代数
人工智能·笔记·深度学习
FakeOccupational4 小时前
【电路笔记 信号】传输线方程:从RLGC推导传输线特性阻抗
笔记
tyqtyq225 小时前
营养餐单规划:AI 科学饮食规划系统的鸿蒙实现
人工智能·学习·华为·职场和发展·生活·harmonyos
鱼听禅5 小时前
Ubuntu学习笔记-安装docker容器
学习·ubuntu·docker