QEMU源码全解析 —— virtio(2)

88 篇文章 19 订阅
本文详细解析virtio框架,包括前端驱动、后端设备及其通信机制。virtio利用半虚拟化技术,通过virtqueue(由vring实现)进行I/O性能优化。前端驱动接收用户请求并封装后通过I/O端口通知QEMU后端设备,后端设备操作物理设备并使用中断机制反馈。virtio架构分为前端驱动、后端设备、virtio层和virtio-ring层,各层功能明确,确保高效的数据传输。
摘要由CSDN通过智能技术生成

接前一篇文章:

本文内容参考:

《趣谈 Linux操作系统 》 —— 刘超, 极客时间

QEMU /KVM》源码解析与应用 —— 李强,机械工业出版社

特此致谢!

上一回对于virtio进行了简介,并说明了其基本原理以及框架。对于virtio框架,再来回顾一下。

virtio框架如下图所示:

virtio是一种利用半虚拟化技术提供I/O性能的框架,其是一种 前后端架构 ,包括 前端驱动(Front-End Driver) 后端设备(Back-End Device) 以及 自身定义的传输协议

  • 前端驱动

前端驱动为 虚拟机 内部的virtio模拟设备对应的驱动,每一种前端设备都需要有对应的驱动才能正常运行。前端驱动的主要作用是:1)接收用户态的请求;2)然后按照传输协议将这些请求进行封装;3)再写I/O端口;4)发送一个通知到 QEMU 的后端设备。

  • 后端设备

后端设备则是在QEMU中,用来接收前端驱动发过来的I/O请求,然后从接收的数据中按照传输协议的格式进行解析。对于网卡等需要实际物理设备交互的请求,后端驱动会对物理设备进行操作,从而完成请求,并且会通过中断机制通知前端驱动。

  • virtio队列

virtio前端和后端驱动的数据传输通过virtio队列(virtio queue,virtqueue)完成,一个设备会注册若干个virtio队列,每个队列负责处理不同的数据传输。这些队列有的是控制层面的队列、有的是数据层面的队列。virtqueue是通过vring实现的。vring是虚拟机和QEMU之间共享的一段环形缓冲区。当虚拟机需要发送请求到QEMU的时候就准备好数据,将数据描述放到vring中,写一个I/O端口。然后QEMU就能够从vring中读取数据信息,进而从内存中读出数据。QEMU完成请求之后,也将数据结构存放在vring中,前端驱动也就可以从vring中得到数据。

此处也有另外一种观点和视角,将virtio架构分为四层:

  • 前端驱动

首先,在虚拟机里面的virtio前端,针对不同类型的设备有不同的驱动程序,但是接口都是统一的。例如,硬盘就是virtio_blk,网络就是virtio_net。

要点:

1) 运行在虚拟机中

2) 针对不同类型的设备有不同的驱动程序,但是与后端驱动交互的接口都是统一的

3) 在Qemu+KVM虚拟化环境中,源码位于KVM源码(Guest 内核)中

  • 后端设备(后端驱动)

其次,在宿主机的QEMU里边,实现virtio后端的逻辑,主要就是操作硬件的设备。例如,通过写一个 物理机 硬盘上的文件来完成虚拟机写入硬盘的操作。再如,向内核协议栈发送一个网络包完成虚拟机对于网络的操作。

要点:

1) 运行在宿主机中

2) 实现virtio后端的逻辑,主要是操作硬件设备 。比如向内核协议栈发送一个网络包完成虚拟机对于网络的操作。

3) 在Qemu+KVM虚拟化环境中,源码位于Qemu源码中

  • virtio层与virtio-ring层

在virtio的前端和后端之间,有一个通信层,里边包括virtio层和virtio-ring层。virtio这一层实现的是虚拟队列接口,算作前后端通信的桥梁;而virtio-ring则是该桥梁的具体实现。

  • virtio层

要点:

1) virtio层实现虚拟队列接口,作为前后端通信的桥梁

2) 不同类型的设备使用的虚拟队列数量不同

3) Linux 内核源码/ 源码位于drivers/virtio/virtio.c中

  • virtio-ring层

要点:

1) virtio-ring层是虚拟队列的具体实现

2) 源码位于Linux内核源码/driver/virtio/virtio_ring.c中

virtio使用virtqueue进行前端与后端的高速通信。 不同类型的设备队列数目不同 。virtio-net使用两个队列,一个用于接收、另一个用于发送;而virtio-blk仅使用一个队列。

如果客户机要向宿主机发送数据,则它会 将数据的buffer添加到virtqueue中 ,然后 通过写入寄存器通知宿主机 。这样宿主机就可以从virtqueue中收到buffer里边的数据了(与前述机制一个意思: 当虚拟机需要发送请求到QEMU的时候就准备好数据,将数据描述放到vring中,写一个I/O端口。然后QEMU就能够从vring中读取数据信息,进而从内存中读出数据 。QEMU完成请求之后,也将数据结构存放在vring中,前端驱动也就可以从vring中得到数据)。

欲知后事如何,且看下回分解。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他