【原创】Linux虚拟化KVM-Qemu分析(十)之virtio驱动
背景
Read the fucking source code!--By 鲁迅A picture is worth a thousand words.--By 高尔基
说明:
- KVM版本:5.9.1
- QEMU版本:5.0.0
- 工具:Source Insight 3.5, Visio
- 文章同步在博客园:
https://www.cnblogs.com/LoyenWang/
1. 概述

- 前篇文章讲完了Qemu中如何来创建Virtio Device,本文将围绕Guest OS中的Virtio Driver来展开;
看一下Guest OS(Linux)中的Virtio框架高层架构图:

- 核心模块为virtio和virtqueue,其他高层的驱动都是基于核心模块之上构建的;
- 显然,本文会延续这个系列,继续分析virtio-net驱动,重心在整体流程和框架上,细节不表;
- virtio-net,又是一个virtio设备,又是一个PCI设备,那么驱动会怎么组织呢?带着问题上路吧。
2. 数据结构
说到驱动怎么能不提linux设备驱动模型呢,感兴趣的朋友可以去看看PCI系列分析文章,简单来说就是内核创建总线用于挂载设备,总线负责设备与驱动的匹配。Linux内核创建了一个virtio bus:

- virtio设备和virtio驱动,通过
virtio_device_id来匹配,而这个都是在virtio规范中定义好的; virtio_device结构中有一个struct virtio_config_ops,函数集由驱动来进行指定,用于操作具体的设备;
本文描述的virtio-net驱动,既是一个virtio设备,也是一个pci设备,在内核中通过结构体struct virtio_pci_device来组织:

- 该结构体中维护了几个IO区域:
Common, ISR, Device, Notify,用于获取virtio设备的各种信息,这个也是由virtio规范决定的; - 通常来说一个virtio设备,由以下几个部分组成:
- Device status field
- Feature bits
- Notifications
- Device Configuration space
- One or more virtqueues
- 从结构体看,它用于充当pci设备和virtio设备的纽带,后续也会在probe函数中针对不同的部分进行对应的初始化;
以总线的匹配视角来看就是这样子的:

3. 流程分析
3.1 virtio总线创建
先看一下virtio总线的创建,virtio bus当然也算是基建了:

bus_register注册virtio总线,总线负责匹配,在匹配成功后调用通用的virtio_dev_probe函数;- 千里姻缘一线牵,当Virtio的ID号能对上时,就会触发驱动探测,所以什么时候进行设备注册呢?
3.2 virtio驱动调用流程
详细的细节,建议阅读之前PCI驱动系列的分析文章,下边罗列关键部分:

- virtio-net设备通过挂在pci总线上,系统在PCI子系统初始化时会去枚举所有的设备,并将枚举的设备注册进系统;
- 系统在匹配上之后,调用设备的驱动;

- PCI设备根据Vendor ID来匹配驱动;
- virtio规范中规定基于PCI的virtio设备,Vendor ID号为:
0x1AF4,因此最终调用的驱动入口为virtio_pci_probe;

- 在probe函数中分配
struct virtio_pci_device结构,前文中也提到过它负责将virtio设备和pci设备绑定到一起,最终会在两个设备驱动的probe函数中完成整体结构的初始化,也就是virtio_pci_probe完成一部分,实际的virtio设备驱动中完成一部分; virtio_pci_modern_probe:该函数的内容就与virtio规范紧密相关了,简单来说,virtio设备都会按照规范填充common、device、isr、notification等功能部分,而virtio_pci_modern_probe函数通过virtio_pci_find_capability去获取对应的能力,并且通过map_capability完成IO空间的映射;virtio_pci_probe中还设置了virtio_pci_config_ops操作函数集,并传递给virtio驱动,在驱动中调用这些回调函数来操作virtio设备;register_virtio_device:向系统注册virtio设备,从而也就触发了virtio总线的匹配操作,最终调用virtio_dev_probe函数;virtio_dev_probe函数中按照virtio规范分阶段设置不同的状态、获取virtio设备的feature等,并最终调用实际设备的驱动程序了;
At last,终于摸到本文要说的virtio-net的驱动的入口了,当然,文章也要戛然而止了。
整体执行流程及框架应该清楚了,细节就留给大家了,待续。。。
参考
https://developer.ibm.com/technologies/linux/articles/l-virtio/
Virtual I/O Device (VIRTIO) Version 1.1
欢迎关注个人公众号,不定期更新技术文章。

【原创】Linux虚拟化KVM-Qemu分析(十)之virtio驱动的更多相关文章
- KVM下windows虚拟机使用virtio驱动
KVM下windows虚拟机默认disk使用的是Qemu IDE硬盘,网卡默认是rtl8139网卡.为了使kvm主机在相同的配置下,有更好的效率,可以将网卡和磁盘替换成virtio的驱动. windo ...
- KVM/QEMU桥接网络设置及kvm资料
KVM/QEMU桥接网络设置 配置kvm的网络有2种方法.其一,默认方式为用户模式网络(Usermode Networking),数据包由NAT方式通过主机的接口进行传送.其二,使用桥接方式(Brid ...
- KVM/QEMU/qemu-kvm/libvirt 概念全解
目录 目录 前言 KVM QEMU KVM 与 QEMU qemu-kvm Libvirt Libvirt 在 OpenStack 中的应用 前言 如果是刚开始接触虚拟机技术的话, 对上述的概念肯定会 ...
- 【原创】Linux虚拟化KVM-Qemu分析(三)之KVM源码(1)
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- 【原创】Linux虚拟化KVM-Qemu分析(一)
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- 【原创】Linux虚拟化KVM-Qemu分析(四)之CPU虚拟化(2)
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- 【原创】Linux虚拟化KVM-Qemu分析(五)之内存虚拟化
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- 【原创】Linux虚拟化KVM-Qemu分析(八)之virtio初探
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- Linux虚拟化技术KVM、QEMU与libvirt的关系(转)
说明:个人理解,KVM是内核虚拟化技术,而内核是不能使用在界面上使用的,那么此时QEMU提供了用户级别的使用界面,相互辅助.当然,单独使用QEMU也是可以实现一整套虚拟机,不过QEMU+KVM基本是标 ...
随机推荐
- XV6学习(11)Lab thread: Multithreading
代码放在github上. 这一次实验感觉挺简单的,特别是后面两个小实验.主要就是对多线程和锁进行一个学习. Uthread: switching between threads 这一个实验是要实现一个 ...
- Left join查询为空
这两个查询,上面查询返回空,下面能正常返回记录 两个表结构: left join 没有匹配上得到的b.dates,b.game_id和b.uid都是null值,在按b.dates=20200317 a ...
- GPLT L2-006 树的遍历(二叉树)
题意: 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 思路: 后序遍历序列 = 左子树遍历序列 + 右子树遍历序列 + 根节点. 中序遍历序列 = ...
- Educational Codeforces Round 102 (Rated for Div. 2) B. String LCM (构造,思维)
题意:给你两个字符串\(a\)和\(b\),找出它们的\(lcm\),即构造一个新的字符串\(c\),使得\(c\)可以由\(x\)个\(a\)得到,并且可以由\(y\)个\(b\)得到,输出\(c\ ...
- Codeforces Round #672 (Div. 2) A. Cubes Sorting (思维)
题意:有一长度为\(n\)的一组数,每次可以交换两个数的位置,问能否在\(\frac{n*(n-1)}{2}-1\)次操作内使得数组非递减. 题解:不难发现,只有当整个数组严格递减的时候,操作次数是\ ...
- Codeforces Round #653 (Div. 3) E1. Reading Books (easy version) (贪心,模拟)
题意:有\(n\)本书,A和B都至少要从喜欢的书里面读\(k\)本书,如果一本书两人都喜欢的话,那么他们就可以一起读来节省时间,问最少多长时间两人都能够读完\(k\)本书. 题解:我们可以分\(3\) ...
- Git 初始化及仓库创建及操作
一.基本信息设置 1.初始化设置用户名 2.初始化设置用户名邮箱 备注:该设置在Github仓库主页显示谁提交了该文件. 二.初始化一个新的Git仓库 1.创建文件夹 mkdir test 2.在文件 ...
- Nginx基础 - 配置静态web服务
1.静态参数配置1)文件读取高效sendfile Syntax: sendfile on | off; Default: sendfile off; Context: http, server, lo ...
- System.Windows.Forms.Help
在开发过程中,基本都需要实现帮助功能,而一般帮助功能就是打开一个帮助文档,System.Windows.Forms提供了Help类用于打开帮助文档,挺方便的. Help类提供的方法如下: Name ...
- mybatis(八)手写简易版mybatis
一.画出流程图 二.设计核心类 二.V1.0 的实现 创建一个全新的 maven 工程,命名为 mebatis,引入 mysql 的依赖. <dependency> <groupId ...