当前位置:   article > 正文

VirtIO实现原理 —— PCI基础(1)

VirtIO实现原理 —— PCI基础(1)

摘要

virtio设备可以基于不同总线来实现,本文介绍基于pci实现的virtio-pci设备。以virtio-blk为例,首先介绍PCI配置空间内容,virtio-pci实现的硬件基础——capability,最后分析PIC设备的初始化以及virtio-pci设备的初始化。

一、PCI配置空间

virtio设备作为pci设备,必须实现pci local bus spec规定的配置空间(最大256字节)前64字节是spec中定义好的,称预定义空间。其中前16字节对所有类型的PCI设备都相同之后的空间格式因类型而不同,对前16字节空间,我称其为通用配置空间。

1. 通用配置空间

通用配置空间如下图所示:

(1)vendor id

厂商ID,用来标识PCI设备出自哪个厂商。这里是0x1af4,来自Red Hat。

(2)device id

厂商下的产品ID。传统virtio-blk设备,这里是0x1001。

(3)revision id

设备版本ID。厂商决定是否使用,这里未使用。

(4)header type

pci设备类型。0x00表示普通设备、0x01表示pci bridge、0x02表示CardBus bridge。virtio是普通设备,这里是0x00。

通用配置空间即PCI配置空间前16字节中的以上4个地方用来识别virtio设备。

(5)command

command字段用来控制pci设备,打开某些功能的开关。对于virtio-blk设备来说,是(0x0507 = 0b01010111)。command的各字段含义如下图所示:

其中,低三位的含义如下:

  • I/O Space位

如果PCI设备实现了IO空间,该字段用来控制是否接收总线上对IO空间的访问;如果PCI设备没有IO空间,该字段不可写。

  • Memory Space位

如果PCI设备实现了内存空间,该字段用来控制是否接收总线上对内存空间的访问;如果PCI设备没有内存空间,该字段不可写。

  • Bus Master位

控制PCI设备是否具有作为Master角色的权限。

(6)status

status字段用来记录pci设备的状态信息。对于virtio-blk设备,是(0x10 = 0b00010000)。status各字段含义如下图所示:

其中,Capabilities List位的含义如下:

  • Capabilities List位

Capabilities List是pci规范定义的附加空间标志位,其意义是允许在pci设备配置空间之后加上额外的寄存器。这些寄存器由Capability List组织起来,用来实现特定的功能,附加空间在64字节配置空间之后,最大不能超过256字节。以virtio-blk设备为例,它标记了这个位,因此在virtio-blk设备的配置空间之后,还有一段空间用来实现virtio-blk的一些特有功能。此处,Capabilities List位为1表示Capabilities Pointer字段(0x34)存放了附加寄存器组的起始地址。这里的地址表示附加空间在PCI设备空间内的偏移。

virtio-blk设备配置空间的内容可以通过lspci命令查看到,如下图所示:

2. virtio配置空间

virtio-pci设备实现pci spec规定的通用配置空间后,设计了自己的配置空间,用来实现virtio-pci的功能。

上面已提到,PCI规范通过status字段的capabilities list位标记自己在64字节预定义配置空间之后有附加的寄存器组,capabilities pointer字段会存放寄存器组链表的头部指针,这里的指针代表寄存器在配置空间内的偏移。如下图所示(仍然是上图中的信息):

pci spec中描述的capabilities list格式如下:第1个字节存放capability ID,标识后面配置空间实现的是哪种capability,第2个字节存放下一个capability的地址。capability ID查阅参见pci spec3.0附录H。

virtio-blk实现的capability有两种一种是MSI-X( Message Signaled Interrupts - Extension)ID为0x11另一种是Vendor SpecificID为0x9。后面一种capability设计目的就是让厂商实现自己的功能。virtio-blk的实现以此为基础。
 

virtio-pci根据自己的功能需求,设计了如下的capabilities布局:

上图中右侧是6个capability,其中5个用做描述virtio-pci的capability,1个用作描述MSI-X的capability。这里我们只介绍用作virtio-pci的capability。右侧描述了virtio-blk的capability布局,左边是每个capability指向的物理地址空间布局。

根据virtio spec的规范,要实现virtio-pci的capabilty,其布局应该如下:

  • cap_vndr

表示capability类型。

  • cap_next

表示下一个capability在pci配置空间的位置。

  • cap_len

表示capability这个数据结构的长度。

  • cfg_type

表示配置类型。cfg_type通过如下取值,将virtio-pci的capability又细分成几类:

3. virtio通用配置空间

capability中最核心的内容是virtio_pci_common_cfg,它是virtio前后端沟通的主要桥梁。common config分两部分:第一部分用于设备配置;第二部分用于virtqueue使用。virtio驱动初始化利用第一部分来和后端进行沟通协商,比如支持的特性(guest_feature),初始化时设备的状态(device_status),设备的virtqueue个数(num_queues)。第二部分用来实现前后端数据传输。后面会详细提到两部分在virtio初始化和数据传输中的作用。virtio_pci_common_cfg数据结构如下:

本文内容较多,为了更好地理解与消化,其余内容放在下一回。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/885093
推荐阅读
相关标签
  

闽ICP备14008679号