Skip to content

virtio.h

TIP

virtio 设备接口定义。 本文件包含了 virtio MMIO (Memory-Mapped I/O) 接口的寄存器定义 以及 virtio 描述符表的结构,这些都是 virtio 设备通信的核心。 这些定义主要基于 QEMU 的实现,并遵循 virtio v1.1 规范。 virtio 规范 v1.1: https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.pdf

TIP

virtio MMIO 控制寄存器,映射到物理地址 0x10001000 开始的内存区域。 寄存器偏移量定义,源自 QEMU (hw/virtio/virtio-mmio.h)。

#define VIRTIO_MMIO_MAGIC_VALUE		0x000
#define VIRTIO_MMIO_VERSION		0x004
#define VIRTIO_MMIO_DEVICE_ID		0x008
#define VIRTIO_MMIO_VENDOR_ID		0x00c
#define VIRTIO_MMIO_DEVICE_FEATURES	0x010
#define VIRTIO_MMIO_DRIVER_FEATURES	0x020
#define VIRTIO_MMIO_QUEUE_SEL		0x030
#define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
#define VIRTIO_MMIO_QUEUE_NUM		0x038
#define VIRTIO_MMIO_QUEUE_READY		0x044
#define VIRTIO_MMIO_QUEUE_NOTIFY	0x050
#define VIRTIO_MMIO_INTERRUPT_STATUS	0x060
#define VIRTIO_MMIO_INTERRUPT_ACK	0x064
#define VIRTIO_MMIO_STATUS		0x070
#define VIRTIO_MMIO_QUEUE_DESC_LOW	0x080
#define VIRTIO_MMIO_QUEUE_DESC_HIGH	0x084
#define VIRTIO_MMIO_DRIVER_DESC_LOW	0x090
#define VIRTIO_MMIO_DRIVER_DESC_HIGH	0x094
#define VIRTIO_MMIO_DEVICE_DESC_LOW	0x0a0
#define VIRTIO_MMIO_DEVICE_DESC_HIGH	0x0a4

TIP

设备状态寄存器 (VIRTIO_MMIO_STATUS) 的位定义。 这些位用于驱动与设备之间的初始化握手过程。

#define VIRTIO_CONFIG_S_ACKNOWLEDGE	1
#define VIRTIO_CONFIG_S_DRIVER		2
#define VIRTIO_CONFIG_S_DRIVER_OK	4
#define VIRTIO_CONFIG_S_FEATURES_OK	8

TIP

设备特性位 (VIRTIO_MMIO_DEVICE_FEATURES)。

#define VIRTIO_BLK_F_RO              5	/* 磁盘为只读设备 */
#define VIRTIO_BLK_F_SCSI            7	/* 支持 SCSI 命令透传 */
#define VIRTIO_BLK_F_CONFIG_WCE     11	/* 支持配置写缓存 */
#define VIRTIO_BLK_F_MQ             12	/* 支持多队列 */
#define VIRTIO_F_ANY_LAYOUT         27  /* 驱动接受任意内存布局 */
#define VIRTIO_RING_F_INDIRECT_DESC 28  /* 支持间接描述符 */
#define VIRTIO_RING_F_EVENT_IDX     29  /* 支持事件索引,用于抑制中断 */

TIP

每个虚拟队列的描述符数量。 该值必须是 2 的幂。

#define NUM 8

TIP

单个 virtio 描述符结构。 描述符用于定义一个供设备访问的内存缓冲区。

struct virtq_desc {
  uint64 addr;
  uint32 len;
  uint16 flags;
  uint16 next;
};
#define VRING_DESC_F_NEXT  1
#define VRING_DESC_F_WRITE 2

TIP

可用环 (Available Ring),由驱动程序填充,用于向设备提供新的缓冲区。

struct virtq_avail {
  uint16 flags;
  uint16 idx;
  uint16 ring[NUM];
  uint16 used_event;
};

TIP

已用环 (Used Ring) 中的一个条目,由设备填充, 用于通知驱动程序已经处理完一个缓冲区。

struct virtq_used_elem {
  uint32 id;
  uint32 len;
};

TIP

已用环 (Used Ring) 结构,设备用它来通知驱动程序已完成的请求。

struct virtq_used {
  uint16 flags;
  uint16 idx;
  struct virtq_used_elem ring[NUM];
  uint16 avail_event;
};

TIP

以下定义特定于 virtio 块设备 (如 virtio-blk 磁盘)。 详见 virtio 规范的 5.2 节。

#define VIRTIO_BLK_T_IN  0
#define VIRTIO_BLK_T_OUT 1

TIP

virtio 块设备请求的头部结构。 一个典型的块设备请求由三个描述符组成: 1. 请求头 (本结构) 2. 数据缓冲区 (读或写) 3. 一个单字节的状态,由设备写回

struct virtio_blk_req {
  uint32 type;
  uint32 reserved;
  uint64 sector;
};