virtio协议1.0 -- 设备初始和操作

84 篇文章 5 订阅
40 篇文章 8 订阅

  • 设备初始化

    • 驱动初始化步骤
    1.  Reset 设备
    2.  设置 ACKNOWLEDGE 状态,通知设备:客户机设别了设备
    3.  设置 DRIVER 状态,客户机找到了对应的驱动
    4.  读取设备的 feature bit 并写会驱动支持的 feature bit 子集到设备,接收feature bit前驱动可能读取 device-specific configuration 进行细粒度校验
    5. 设置 FEATURES_OK,此后,驱动不能在接受更多新的 feature bit
    6. 读取设备状态,确保FEATURES_OK 写入成功,如果不是 FEATURES_OK,说明特性协商不成功,设备不可用
    7. 进行 device-specific 设定,包括配置 virtio configuration space,设定 virtqueue等
    8. 设定 DRIVER_OK,表示设备可用,驱动加载完成
    • 如果任何一个步骤有错,驱动设置FAILED状态,放弃设备初始化
    • 在 DRIVER_OK 前,不能下发 KICK
    • 区别
      • Legacy 设备不支持 FEATURES_OK 状态,没有机会检查兼容性
      • Legacy 设备没有明确的feature协商状态
      • 步骤5,6没有;
  • 设备操作

  • 两种设备操作:发送(发送给设备,tx)和接收(从设备接收,rx)
  • 发送
    • 驱动发送buffer到设备的一个或多个TX队列
      1. 驱动将buffer存到desc表的free desc中,可能desc成链
      2. 驱动将desc链的第一个desc的idx写入avail ring的生产位置(avail ring->idx)
      3. 重复步骤1,2进行批量操作
      4. 加入内存屏障
      5. 增加 avail ring->idx,指向下一次驱动会生产填入的位置
      6. KICK没有被抑制,发送KICK
    • avail ring 的填写不会超过一圈,因为 ring深度和desc 表大小一样,不会填写超过一个ring深度的desc到avail ring
    • 最大queue size是32768
    • 用buffer填写desc表中的desc
      • 0个或多个客户物理地址连续的设备可读buffer
      • 后面是0个或多个客户物理地址连续的设备可写buffer
      • 填充到一个desc链里面
      • 填充buffer b的步骤
        • 从desc表取得下一个空闲的desc(d)
        • d.addr = b 的客户物理地址
        • d.len = b 的长度
        • 如果 b 是设备可写, d.flags |= VIRTQ_DESC_F_WRITE;否则 d.flag = 0
        • 如果后面还有下一个buffer
          • d.next = 下一个空闲desc的idx
          • d.flags |= VIRTQ_DESC_F_NEXT
      • 注意填充buffer前驱动需要确认有足够多的空闲desc可以使用
    • 更新 avail ring
      • desc 表头是第一个desc(d)的idx,填入avail ring中
      • 驱动可能一次加入多个desc链
    • 更新 avail ring -> idx
      • avail ring -> idx 单向自增,直到65535
      • 驱动更新   avail ring -> idx
      • 设备根据  avail ring -> idx 来取desc表和buffer的内存
      • 驱动
        • 驱动在更新 avail ring -> idx 前,必须加入内存屏障,保证设备能读到desc链和buffer 
    • 向设备发送KICK
      • 根据不同的总线类型有不同方式的KICK
      • 操作代价很高
      • 设备可能会对KICK进行限流抑制
      • 驱动使用更新后的avail ring -> idx(下一个位置)来对是否抑制进行判断
      • 驱动
        • 驱动在读取flags 或 avail_event之前,必须加入内存屏障
    • 接收
      • 设备使用了desc所指向的内存后(读或写),会发送中断给驱动
      • 驱动可能关闭中断,使能后,驱动需要再次 used ring->idx 
    • 配置变更中断
      • device-specific configuration信息在运行期间可能发生变化,设备需要发送Config chang 中断给设备
      • 设备设置了 DEVICE_NEEDS_RESET 状态,会触发 Config chang 中断
  • 设备清理移除

    • 设置 DRIVER_OK 状态,队列的配置认为了被激活
    • 设备发生重启,队列就是不可用状态
    • 驱动
    • 写入available ring后的desc不能被修改
    • 队列使能后,available idx只能单向增长

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值