虚拟化之---virtio通信

一、理解virtio的背景

        我们知道虚拟化hypervisor大的类型分为两种,全虚拟化和半虚拟化。

        在全虚拟化的解决方案中,guest VM 要使用底层 host 资源,需要 Hypervisor 来截获所有的请求指令,然后模拟出这些指令的行为,这样会带来很多性能上的开销。半虚拟化通过底层硬件辅助的方式,将部分没必要虚拟化的指令通过硬件来完成,Hypervisor 只负责完成部分指令的虚拟化,要做到这点,需要 guest 来配合,guest 完成不同设备的前端驱动程序,Hypervisor 配合 guest 完成相应的后端驱动程序,这样两者之间通过某种交互机制就可以实现高效的虚拟化过程。

        让我们以uart举例来说明和理解:

        在完全虚拟化的情况下,当 guest VM 需要与物理串口进行通信时,它会发出读取或写入串口数据的指令。Hypervisor 需要截获这些指令,并模拟出串口的行为,将数据传递给物理串口或从物理串口接收数据。

        在半虚拟化的情况下,底层硬件提供了辅助机制,使得部分指令可以直接由硬件完成,而无需 Hypervisor 的干预。对于 UART,底层硬件可能提供了一种机制,使 guest VM 的前端驱动程序能够直接访问物理串口,而无需 Hypervisor 的介入。这样,当 guest VM 发出读取或写入串口数据的指令时,前端驱动程序可以直接与物理串口进行交互,完成数据的传输。

        然而,仍然有一些指令需要 Hypervisor 的虚拟化支持。例如,当 guest VM 需要打开或关闭串口时,这些操作可能涉及到对底层硬件的配置,需要 Hypervisor 的参与来确保正确的虚拟化行为。在这种情况下,Hypervisor 会截获相关指令,并模拟出打开或关闭串口的行为。

        通过底层硬件的辅助,半虚拟化可以将一部分不必要的指令交给硬件来完成,减轻了 Hypervisor 的负担,提高了虚拟化的效率。在 UART 的例子中,底层硬件提供了直接访问物理串口的能力,使得部分串口操作可以直接由 guest VM 的前端驱动程序完成,而 Hypervisor 只需要处理一些需要虚拟化支持的操作。

        如果是全虚拟化,比如以kvm为例,大致的数据流是如下:

        整个数据通路如下:

        a.Guest VM 发送数据: Guest VM 中的应用程序或驱动程序向虚拟的 UART 设备发送数据。

        b.QEMU 截获操作: QEMU 截获了 guest VM 中对虚拟 UART 设备的操作。

        c.QEMU 模拟并转发: QEMU 根据截获的操作,将数据发送给真实的 UART 设备。这可能涉及到与主机操作系统进行交互,以确保数据正确地传递给物理 UART 设备。QEMU相当于一个应用,就可以使用host硬件资源了,比如在windows下就是设备管理器的物理设备,linux下就是dev对应的设备。

        d.Host 主机的 UART 设备接收数据: Host 主机上的真实 UART 设备接收到数据。

二、virtio架构

virtio 和 virtio-ring 可以看做是一层,virtio-ring 实现了 virtio 的具体通信机制和数据流程.

三、virtio通信机制

Front-End Virtio driver (a.k.a. frontend driver, or FE driver in this document)

Virtio adopts a frontend-backend architecture, which enables a simple but flexible framework for both frontend and backend Virtio driver. The FE driver provides APIs to configure the interface, pass messages, produce requests, and notify backend Virtio driver. As a result, the FE driver is easy to implement and the performance overhead of emulating device is eliminated.

Back-End Virtio driver (a.k.a. backend driver, or BE driver in this document)

Similar to FE driver, the BE driver, runs either in user-land or kernel-land of host OS. The BE driver consumes requests from FE driver and send them to the host’s native device driver. Once the requests are done by the host native device driver, the BE driver notifies the FE driver about the completeness of the requests.

Straightforward: Virtio devices as standard devices on existing Buses

Instead of creating new device buses from scratch, Virtio devices are built on existing buses. This gives a straightforward way for both FE and BE drivers to interact with each other. For example, FE driver could read/write registers of the device, and the virtual device could interrupt FE driver, on behalf of the BE driver, in case of something is happening. Currently Virtio supports PCI/PCIe bus and MMIO bus. In ACRN project, only PCI/PCIe bus is supported, and all the Virtio devices share the same vendor ID 0x1AF4.

Efficient: batching operation is encouraged

Batching operation and deferred notification are important to achieve high-performance I/O, since notification between FE and BE driver usually involves an expensive exit of the guest. Therefore batching operating and notification suppression are highly encouraged if possible. This will give an efficient implementation for the performance critical devices.

Standard: virtqueue

All the Virtio devices share a standard ring buffer and descriptor mechanism, called a virtqueue, shown in Figure 6. A virtqueue is a queue of scatter-gather buffers. There are three important methods on virtqueues:

  • add_buf is for adding a request/response buffer in a virtqueue
  • get_buf is for getting a response/request in a virtqueue, and
  • kick is for notifying the other side for a virtqueue to consume buffers.

The virtqueues are created in guest physical memory by the FE drivers. The BE drivers only need to parse the virtqueue structures to obtain the requests and get the requests done. How virtqueue is organized is specific to the User OS. In the implementation of Virtio in Linux, the virtqueue is implemented as a ring buffer structure called vring.

In ACRN, the virtqueue APIs can be leveraged directly so users don’t need to worry about the details of the virtqueue. Refer to the User VM for more details about the virtqueue implementations.

virtqueue的定义:

virtio核心代码:

Kconfig              virtio_balloon.c     virtio_input.c       virtio_pci_common.c  virtio_pci_legacy.c  virtio_ring.c
Makefile             virtio.c             virtio_mmio.c        virtio_pci_common.h  virtio_pci_modern.c

 比如guest 要向 host 发送数据,首先,guest 通过函数 virtqueue_add_buf 将存有数据的 buffer 添加到 virtqueue 中,然后调用 virtqueue_kick 函数,virtqueue_kick 调用 virtqueue_notify 函数,通过写入寄存器的方式来通知到 host。host 调用 virtqueue_get_buf 来获取 virtqueue 中收到的数据。

当 guest 向 virtqueue 中写数据时,实际上是向 desc 结构指向的 buffer 中填充数据,完了会更新 available ring,然后再通知 host。

当 host 收到接收数据的通知时,首先从 desc 指向的 buffer 中找到 available ring 中添加的 buffer,映射内存,同时更新 used ring,并通知 guest 接收数据完毕

四、virtio总线案例

 FE i2c driver <-> BE i2c driver <--> i2c client <-> i2c resource manager <-> i2c phsyical driver

说明:其中be driver可以在host的应用层来实现,而不是叫driver就要放到host的驱动中。在虚拟化厂家的be driver中收到guest os发过来的virtqueue 的notify消息后,然后进行相关处理。

SPI也是类似:

dtsi中配置virt spi:

        spi1:spi1@11100001{
                compatible =  "platform,virtio-spi"
                                  }

driver中添加spi-virtio.c相关驱动。

然后应用层可以看到/dev/spi节点,这样guest就可以正常操作虚拟出的spi设备了。

参考官网ACRN:

What is ACRN — Project ACRN™ v 1.6 documentation

参考QNX:

https://www.qnx.com/developers/docs/7.0.0/index.html#com.qnx.doc.hypervisor.nav/topic/bookset.html可以参考博文(写的非常好):

https://www.qnx.com/developers/docs/7.0.0/index.html#com.qnx.doc.hypervisor.nav/topic/bookset.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/596407.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python-dict序列化的数据为啥前后不一致

前情提要及背景:流式数据的二次处理终结篇-CSDN博客 假如直接将dict进行str,那么编码数据都是一致的,但是在postman上就表现不那么好看,如下: 而之前的显示如下: 其中的差别就是单引号与双引号的差别了。 采用如下方案无疑是最笨的方法了: 在Python中,如果你想将处理…

各城市-人口就业和工资数据(1978-2022年)

这份数据收集了1978年至2022年间300多个地级市的人口、就业和工资等数据。涵盖的指标包括从业人员数量、平均工资水平、人口密度等&#xff0c;通过这些数据可以深入了解中国各地城市的人口结构、就业状况以及工资水平的变化趋势。这些数据对于研究城市发展、劳动力市场以及区域…

微积分 --- 偏导数,方向导数与梯度(二)

方向导数 上图为一温度图&#xff0c;所反映的是加利福利亚洲和内华达州在十月的一天下午三点的温度。其中&#xff0c;图中的每一点都是温度T关于x,y的函数&#xff0c;即T(x,y)。对于图中的Reno市而言&#xff0c;沿着x方向的偏导反映的是温度沿着x方向&#xff0c;即沿着东方…

【搜索技能】外链

文章目录 前言一、外链是什么&#xff1f;二、如何进行外链调查&#xff1f;总结 前言 今儿因为在搜索一个很感兴趣的软件&#xff0c;但是软件信息所在的网址非常有限。因此产生了一个念头&#xff1a;我能不能找到所有的包含了或者是引用了这个网站的网站呢? 调查之下&…

五道链表习题,只过思路

建议先过一遍&#xff1a;保研机试前的最后七道链表题-CSDN博客 第一题 82. 删除排序链表中的重复元素 II - 力扣&#xff08;LeetCode&#xff09; 是不是似曾相识的感觉&#xff0c;好像数组顺序去重&#xff0c;请看&#xff1a;保研机试前的最后七道数组题-CSDN博客 第二…

幻兽帕鲁游戏主机多少钱?幻兽帕鲁游戏服务器一个月仅需32元

随着游戏产业的蓬勃发展&#xff0c;腾讯云紧跟潮流&#xff0c;推出了针对热门游戏《幻兽帕鲁Palworld》的专属游戏服务器。对于广大游戏爱好者来说&#xff0c;这无疑是一个激动人心的消息。那么&#xff0c;腾讯云幻兽帕鲁游戏主机到底多少钱呢&#xff1f;让我们一起来揭晓…

编程基础学什么课程内容

编程基础学习的课程内容有&#xff1a;程序设计基础、算法与数据结构、计算机科学原理、面向对象编程、网页开发基础等课程内容&#xff0c;以下是上大学网 (www.sdaxue.com)整理的具体课程或技能领域内容&#xff0c;供大家参考&#xff01; 程序设计基础&#xff08;或计算机…

重学java 29.经典接口

光阴似箭&#xff0c;我好像跟不上 —— 24.5.6 一、java.lang.Comparable 我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话&#xff0c;直接使用比较运算符即可&#xff0c;但是引用数据类型是不能直接使用比较运算符来比较大小的。那么&#xff0c;如何解决这个…

Vue MVVM这一篇就够啦!

Vue vs React 相似之处: 它们都有使用 Virtual DOM虚拟DOM-CSDN博客&#xff1b;提供了响应式&#xff08;Reactive&#xff09;和组件化&#xff08;Composable&#xff09;的视图组件。将注意力集中保持在核心库&#xff0c;而将其他功能如路由和全局状态管理交给相关的库。R…

数塔问题(蛮力算法和动态规划)

题目&#xff1a;如下图是一个数塔&#xff0c;从顶部出发在每一个节点可以选择向左或者向右走&#xff0c;一直走到底层&#xff0c;要求找出一条路径&#xff0c;使得路径上的数字之和最大&#xff0c;及路径情况。(使用蛮力算法和动态规划算法分别实现&#xff09; #include…

AI预测福彩3D第10套算法实战化赚米验证第2弹2024年5月6日第2次测试

由于今天白天事情比较多&#xff0c;回来比较晚了&#xff0c;趁着还未开奖&#xff0c;赶紧把预测结果发出来吧~今天是第2次测试~ 2024年5月6日福彩3D预测结果 6-7码定位方案如下&#xff1a; 百位&#xff1a;3、4、1、7、8、9 十位&#xff1a;4、5、3、7、8、9 个位&#x…

# 怎么关闭 win10 系统中自带的【文件预览】功能?关闭WIN10【文件预览】功能的方法

怎么关闭 win10 系统中自带的【文件预览】功能&#xff1f;关闭WIN10【文件预览】功能的方法 win10 系统中自带的【文件预览】功能&#xff0c;默认是开启状态的&#xff0c;如果需要关闭它&#xff0c;一步搞定。 1、打开电脑文件浏览器&#xff0c;随便进入有文件的一个文件…

《QT实用小工具·五十五》带有标签、下划线的Material Design风格输入框

1、概述 源码放在文章末尾 该项目实现了一个带有标签动画、焦点动画、正确提示、错误警告的单行输入框控件。下面是demo演示&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef LABELEDEDIT_H #define LABELEDEDIT_H#include <QObject> #include <QWidget>…

截取字符串的3种方法

一、截取字符串的实现 在C语言中&#xff0c;没有直接截取字符串的库函数&#xff0c;但是咱们可以借助其他函数实现这个功能。 1&#xff0e;最简单的方法 如果只是直接输出一个字符串的子串&#xff0c;只需要一个简单的printf函数即可。 #include <stdio.h> int m…

寒武纪及瑞芯微平台调用加速调研

文章目录 1 寒武纪加速平台简介1.1 加速平台简介1.1.1 算力硬件1.1.2 配套软件 1.2 部署流程简介1.3 部署环境搭建1.3.1 安装驱动1.3.2 安装CNToolKit1.3.3 配置模型移植开发环境 1.4 模型部署1.4.1 模型转换旧文件格式1.4.2 量化模型生成1.4.3 验证结果1.4.4 离线模型生成 1 寒…

LIUNX系统编程:进程池的实现

1.什么是进程池 每一个可执行程序&#xff0c;在被执行前都要转化为进程&#xff0c;操作系统都要为其创建PCB&#xff0c;地址空间&#xff0c;页表&#xff0c;构建映射关系&#xff0c;进程池就是创建进程时&#xff0c;创建很多个进程&#xff0c;如果要执行程序&#xff…

HTML_CSS学习:背景、鼠标相关属性

一、背景相关属性 相关代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>背景相关属性</title><style>body{background-color: greenyellow;}div{width: 400px;height: …

C语言-分支和循环语句、函数、数组、操作符、指针、结构体

目录 一、scanf和getchar二、产生随机数函数三、辗转相除法求最大公约数四、函数的参数4.1 实际参数&#xff08;实参&#xff09;4.2 形式参数&#xff08;形参&#xff09;4.3 内存分配 五、函数的调用5.1 传值调用5.1 传址调用 六、函数的声明和定义6.1 函数的声明6.2 函数的…

Day62:单调栈 LeedCode503. 下一个更大元素 II 42. 接雨水

503. 下一个更大元素 II 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数…

服务运维问题

2024-05-01&#xff08;docker 部署的 jar包自动关闭&#xff09; 查询运行情况&#xff1a;处于退出状态 docker ps -a 查询日志&#xff1a;看不出问题 docker logs -f --tail1000 demo-java 查询关于java服务日志&#xff1a;Out of memory: Kill process 16236 (java) …