进行VIRTIO DMA相关工作,看过的同学都知道,VIRTIO DMA 中非常复杂的其实不是desc表什么的,而是index的更新,什么index,last_xx_index等等,搞得人云里雾里,而且网上大部分都是前后端分开描述,而且都是基于代码讲解,更让入门的同学不知所踪。今天我们就在这个文章里面,对virtio DMA的过程进行白话描述,不涉及具体代码,只讲清原理和设计原因为目的
虚拟化模拟的就是后端的虚拟硬件,我们在这里就认为他们是硬件,所以本位把后端成为HW;前端驱动在本文里面成为SW。
我们知道virtqueue, virtqueue由三部分组成,avail ring, used ring 和 desc 表。desc表最好理解,记录了一系列描述符,每个描述符指向一个真的内存。
不论是TX方向,还是RX方向,avail ring 是软件SW进行生产写入,硬件HW进行读取消费,SW作为生产者对avail ring进行填充,硬件HW对avail ring的内容进行消费,这个结论需要切记。
与之对应,不论是TX方向,还是RX方向,used ring 是硬件进行生产写入,软件SW进行读取消费,HW作为生产者对used ring进行填充,软件SW对used ring的内容进行消费,这个结论这也要切记!
下图就是整个virtqueue的结构,
avail ring 最前面是flag和index,按前面描述,avail->index 和 avail->ring[] 的内容都是SW进行填充和更新,SW每填充一个ring[],就会对avail->index进行++操作,并发送kick通知给硬件HW。硬件里面维护了一个数字称为 HW_LAST_AVAIL_IDX,每当收到KICK的时候,就会检查 HW_LAST_AVA