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

接前一篇文章:

本文内容参考:

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

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

特此致谢!

virtio简介

对于一台虚拟机而言,除了要虚拟化CPU和内存,当然也要虚拟化外部设备,这其中最为典型和关键的是存储和网络。那么这些外部设备应该如何虚拟化呢?

  • 全虚拟化

当然,一种方式(方案)还是完全虚拟化。使用QEMU完全模拟设备,比如,有什么样的硬盘或网卡设备,就使用QEMU模拟一个一模一样的软件的硬盘和网卡设备。这样在虚拟机里边的操作系统看来,使用这些设备和使用物理设备是一样的。传统的设备模拟中,虚拟机内部设备驱动完全不知道自己处在虚拟化环境中。对于网络和存储等,I/O操作会走完整的“虚拟机内核栈 -> QEMU -> 宿主机内核栈”。虽然在这种方式下,做到了完全而真正的虚拟化,但QEMU又充当了翻译官的角色,每个指令都需要与翻译,在此过程(“虚拟机内核栈 -> QEMU -> 宿主机内核栈”)中,会产生很多的VM Exit和VM Entry,性能很差,实在是太慢了。

  • 半虚拟化

另一种方式(方案)是半虚拟化虚拟机里边的操作系统不是一个通用的操作系统,它知道自己是运行在虚拟机里边的也清楚使用的硬盘和网络等设备都是虚拟的,应该加载特殊的驱动才能运行。这些特殊的驱动往往要通过虚拟机里外配合工作的模式,来加速对于物理存储设备和网络设备(等)的使用。而本段的主角——virtio就是采用的此种方式。

virtio方案是旨在提高性能的一种优化方案,在该方案中,虚拟机能够感知到自己处于虚拟化环境,并且会加载相应的virtio总线驱动和virtio设备驱动。

virtio基本原理

在虚拟化技术的早期,不同的虚拟化技术会针对不同硬盘(物理存储)和网络等设备实现不同的驱动。虚拟机里边的操作系统也要根据不同的虚拟化技术及物理存储和网络设备,选择加载不同的驱动。但是,由于硬盘设备和网络设备太多了,驱动纷繁芜杂。

后来就慢慢形成了一定的标准,这就是virtio。顾名思义,virtio就是virtual io的缩写,也即虚拟化I/O设备的意思。virtio负责对于虚拟机提供统一的接口。也就是说,在虚拟机里边的操作系统加载的驱动,以后都统一加载virtio就可以了。

半虚拟化的基本原理如下图所示:

上图主要包括两部分内容:一个是VMM创建出模拟的设备;另一个是操作系统内部安装好该模拟设备的驱动,这个驱动和设备之间使用对应的接口进行通信。

以e1000网卡为例,在传统的全虚拟化方式下,虚拟机内核中的网卡驱动还是与具体的硬件设备相同,也就是说QEMU模拟的是e1000的网卡。虚拟机操作系统还是通过传统的方式进行包的收发。e1000以及其它模拟设备网卡的驱动在收发包的时候,会有很多次的写网卡寄存器或者IO端口的操作,这会导致VM Exit,使得网卡的性能比较差(与上边提到的一致)。

而在半虚拟化环境下,设备和驱动都是新的、专门用来适应虚拟化环境的。虚拟机中的设备驱动与QEMU中的虚拟网卡设备定义一套自己的协议进行数据传输,通过自己约定的接口,可以很方便地进行通信。

virtio即是这样一种利用半虚拟化技术提供I/O性能的框架。virtio框架如下图所示:

virtio是一种前后端架构,包括前端驱动(Front-End Driver)后端设备(Back-End Device)以及自身定义的传输协议。通过传输协议,virtio不仅可以用于QEMU/KVM方案,也可以用于其它的虚拟化方案。如虚拟机可以不必是QEMU,而也可以是其它类型的虚拟机;后端不一定要在QEMU中实现,也可以在内核中实现(这实际上就是vhost方案)。

接下来对以上三个组件做简单介绍:

  • 前端驱动

前端驱动为虚拟机内部的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中得到数据。

vring的基本原理如下图所示:

vring包含三个部分:

第一部分是描述符表(Descriptor Table),用来描述I/O请求的传输数据信息,包括地址、长度等信息;

第二部分是可用的vring(Available Vring),这是前端驱动设置的表示后端设备可用的描述符表中的索引

第三部分是已经使用的vring(Used Vring),这是后端设备在使用完描述符表后设置的索引,这样前端驱动可以知道哪些描述符已经被用了。

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt Desktop Widgets 控件绘图原理逐步分析拆解

Qt 是目前C语言首选的框架库。之所以称为框架库而不单单是GUI库,是因为Qt提供了远远超过GUI的功能封装,即使不使用GUI的后台服务,也可以用Qt大大提高跨平台的能力。 仅就界面来说,Qt 保持各个平台绘图等效果的统一,并…

ActiveMQ任意文件写入漏洞(CVE-2016-3088)

简述:ActiveMQ的fileserver支持写入文件(但是不支持解析jsp),同时也支持移动文件。所以我们只需要先上传到服务器,然后再移动到可以解析的地方即可造成任意文件写入漏洞。我们可以利用这个漏洞来上传webshell或者上传定时任务文件。 漏洞复现 启动环境 …

C++学习笔记(十一)------has_a和use_a关系

文章目录 前言 一、has_a关系 1.1 has_a概念 1.2 has_a中构造和析构的顺序 1.3 has_a对象的内存情况 二、use_a关系(友元关系) 1.友元函数: 2.友元类 3 使用多文件编程的方式重新编辑上述代码 总结 前言 随着技术的革新,出现各种各…

到底什么是DevOps

DevOps不是一组工具,也不是一个特定的岗位。在我看来DevOps更像是一种软件开发文化,一种实现快速交付能力的手段。 DevOps 强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的…

高通平台开发系列讲解(USB篇)MBIM 调试记录

文章目录 一、MBIM网卡显示二、未插入SIM卡情况显示三、SIM 无服务四、正常五、抓取QXDM log 分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文主要介绍MBIM网卡调试过程的记录。 一、MBIM网卡显示 若显示黄标,则检查mbimd进程是否正常,mbim驱动是否正常。 二…

Http模块

Http模块 1.创建http服务 //导入http模块 const http require(http)//创建服务对象 const server http.createServer((request,response)>{response.end(Hello HTTP Server) })// 监听端口,启动服务 server.listen(9000,()>{console.log(服务已启动....);…

class076 区间dp-上【算法】

class076 区间dp-上【算法】 算法讲解076【必备】区间dp-上 code1 1312. 让字符串成为回文串的最少插入次数 // 让字符串成为回文串的最少插入次数 // 给你一个字符串 s // 每一次操作你都可以在字符串的任意位置插入任意字符 // 请你返回让s成为回文串的最少操作次数 // 测试…

深度学习 Day11——T11优化器对比实验

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 文章目录 前言一、我的环境二、代码实现与执行结果1.引入库2.设置GPU(如果使用的是CPU可以忽略这步)3.导入数据4.查…

单位的网络能监控微信聊天记录吗

有人在后台咨询,单位的网络能监控微信聊天记录吗 先来回答这个问题: 是的,公司网络在特定情况下可以监控到微信聊天记录。 1,公司可能会通过网络监控软件来监控员工的网络活动。比如说我们经常使用的,域之盾软件&…

scala表达式

1.8 表达式(重点) # 语句(statement):一段可执行的代码# 表达式(expression):一段可以被求值的代码,在Scala中一切都是表达式 - 表达式一般是一个语句块,可包含一条或者多条语句,多条语句使用“…

基于SSM框架的在线投票系统

基于SSM框架的在线投票系统 文章目录 基于SSM框架的在线投票系统 一.引言二.系统设计三.技术架构四.功能实现五.界面展示六.源码获取 一.引言 随着科技的不断发展,人们对于民主参与的需求也越来越高。在线投票系统应运而生,为人们提供了便捷、高效的投票…

ImmunityCanvas7.26安装详细教程

ImmunityCanvas7.26 大家想必都已经知道了Immunity Canvas7.26武器于2021年3月2日泄露了吧那我就废话不多说了。 很多人已经有了这款工具不得不说这工具很nice如果要买的话一年的话3万美金我的天我穷了。。 简单介绍 Immunity Canvas是美国ImmunitySec出品的安全漏洞检测工具…