当前位置: 首页 > news >正文

用户态驱动的两种方式-ixy学习

介绍

在Linux下有两种启用用户态驱动的子系统:一个是UIO,另一个是VFIO,ixy这两种都支持。 UIO通过虚拟文件系统sysfs下的内存映射文件来暴露所有必要的接口以完成用户态的驱动。这些基于文件的系统调用接口给了我们充足的权限来获取设备资源而不需要写任何内核代码。ixy要卸载到所给PCI设备的任何内核驱动以避免冲突,比如,当ixy正在运行时,NIC的任何驱动都不会被加载。

VFIO提供了更多的特性:IOMMU和中断,且这些只能由VFIO提供。然而,这些特性会带来额外的复杂度开销:它要求PCIe设备和通用的vfio-pci驱动绑定,然后它会在指定的文件上通过ioclt系统调用提供API。

第一个需要理解的是用户态驱动如何与设备打交道的,也就是理解驱动是如何写在用户态的。驱动能够与PCIe设备通信的两种途径:驱动能初始化到设备BAR的访问通道或设备能初始化DMA通道映射到任何的主存储区。BARs是由设备暴露配置信息给驱动,并给驱动来控制寄存器。这些寄存器可以通过内存映射IO方式(MMIO)获得,也可以通过依赖于设备的X86 独立IO获得,后者在PCIE设备上不推荐使用。

操作设备寄存器

MMIO将设备IO与内存空间映射起来,比如从这块内存区域读取或写入来完成向设备的接收或发送操作。UIO用虚拟文件系统暴露所有的BARs,这样有权限的程序就可以简单地把BARs映射到它自己的地址空间。VFIO提供了一个ioctl返回映射到这片区域的内存地址。设备通过这个接口暴露出它的配置寄存器,这样用户就可以用读写的方式来访问寄存器了。例如,ixgbe网卡设备通过BAR0地址空间暴露出所有的配置寄存器,状态寄存器和调试寄存器。这些映射的实现是在pci.c文件的pci_map_resource()函数和在libixy-vfio.c文件的vfio_map_region()函数里。不幸的是,VirtIO(在我们的实现与VirtualBox的兼容版本中)是基于PCI而不是在 PCIe ,其 BAR 是一个 IO 端口资源,必须使用古老的 IN 和 OUT x86 指令进行访问,这些指令需要IO 权限。

Linux能通过ioperm授予进程必要的权限,DPDK为他们的VirtIO驱动使用这样的通道。我们发现这种初始化工作太复杂,因为它需要解析 PCIe 配置空间或 procfs 和 sysfs 中的文本文件来初始化。Linux uio 通过sysfs的文件暴露出BAR空间,但与 MMIO 对应项不同,这些文件无法进行 mmap。这些文件能被打开,并通过通用的读写调用来访问,然后由内核转换为相应的 IO 端口命令。我们发现这样做更便于使用和理解,但由于所要求的系统调用而变得更慢。实现代码可见pci.c文件内的pci_open_resource()函数,device.h文件内的read/write_ioX()函数。

一个潜在的陷阱是读取和写入的确切大小很重要,例如,访问单个 32 位寄存器,用 2 个 16 位读取通常会失败,并且用一次大的读取来尝试读取多个小单位的寄存器通常是不支持的。确切的语义取决于设备,Intel的ixgbe NIC仅公开支持部分读取的 32 位寄存器(除了读取时清除寄存器),但不是部分写入。VirtIO 使用不同的寄存器大小,特别是,任何访问宽度应该是可以在我们正在使用的模式下工作的,事实上对齐且大小正确的访问可以可靠地工作的。

用户态的DMA

DMA是由PCIe设备初始化的,并允许它读写任意的物理地址。这被用来在驱动和网卡之间传输数据包和存放在DMA上的数据包描述符(指向数据包)。DMA需要在设备的PCI配置空间里显示地使能,我们在pci.c的enable_dma()函数里实现了这个使能,同样在libixy-vfio.c的vfio_enable_dma()函数为VFIO同样实现了这个使能。

DMA的内存分配在UIO和VFIO之间是不同的。

UIO的DMA内存分配

用于DMA的内存空间必须是常驻于物理内存区域。mlock(2)能用来禁用swapping。然后,这仅能保障页被内存保持支持,并不保障分配的内存物理地址保持始终一样。Linux的页迁移机制能在任何时间改变用户空间分配的任何页的物理地址,比如,来实现传输巨页和NUMA选项等。Linux 没有实现显式分配的大页(x86 上的 2 MiB 或1 GiB 页面)的页面迁移。因而ixy使用巨页来简单地分配连续的大的物理内存。在用户空间分配巨页被所有的用户态驱动采用,但他们经常是作为性能提升来使用,尽管可靠的DMA内存分配也至关重要。因为用户态驱动也需要能讲它的虚拟地址转换为物理地址,这可以通过procfs文件/proc/self/pagemap来实现,这种传输逻辑在memory.c文件的virt_to_phys()函数里实现。

VFIO的DMA内存分配

之前的DMA内存分配机制是X86平台上的Linux的特殊机制,而不是可移植的。VFIO的特点是,它是可移植的,他内部调用dma_alloc_coherent()函数来分配内存,就像其他的内核态驱动那样做。这个系统调用简化了所有的复杂细节并在我们的驱动里以libixy-vfio.c文件的vfio_map_dma()函数来实现。它需要一个IOMMU,并配置必要的映射来为物理设备使用虚拟地址。

DMA和缓存一致性

这两种实现都要求我们的CPU架构满足缓存一致的DMA访问。老式的CPU可能不支持这个功能,并要求在DMA数据能被设备读到之前把缓存上的数据同步到内存。现代的CPU没有这个问题。实际上,为实现高速数据IO的一个主流技术是DMA访问并不真的到内存,而是到新CPU架构的缓存上。

用户态的中断

VFIO的特点是对中断全支持,具体设置函数为libixy-vfio.c文件内的vfio_setup_interrupt()函数,为VFIO使能一个指定的中断,并将它与一个eventfd的文件描述符绑定。ixgbe.c里的enbale_msiz_interrupt()函数为设备上的一个队列配置中断。中断被映射到一个文件描述符上,被系统调用如epoll检测,一般进入睡眠状态,直到中断发生,请见libixy-vfio.c文件内的vfio_epoll_wait()函数。

相关文章:

用户态驱动的两种方式-ixy学习

介绍在Linux下有两种启用用户态驱动的子系统:一个是UIO,另一个是VFIO,ixy这两种都支持。 UIO通过虚拟文件系统sysfs下的内存映射文件来暴露所有必要的接口以完成用户态的驱动。这些基于文件的系统调用接口给了我们充足的权限来获取设备资源而…...

机器学习 | 线性回归(单变量)

前文回顾:机器学习概述📚线性回归概念我们要使用一个数据集,数据集包含俄勒冈州波特兰市的住房价格。在这里,我要根据不同房屋尺寸所售出的价格,画出我的数据集。比方说,如果你朋友的房子是 1250 平方尺大小…...

C++基础知识【3】控制语句

目录 前言 一、条件语句 1.1、if 语句 1.2、if-else 语句 1.3、switch 语句 二、循环语句 2.1、while 循环 2.2、do-while 循环 2.3、for 循环 三、跳转语句 3.1、break语句 3.2、continue语句 3.3、goto语句 四、一些新特性 4.1、if 语句和 switch 语句…...

ImportError: Can not find the shared library: libhdfs3.so解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...

Qt插件开发总结5--主界面嵌入插件UI

文章目录一、前言二、效果展示三、嵌入插件UI1、插件接口文件添加UI指针2、插件子项目工程建立UI类3、插件类中创建UI类、使UI指针指向创建的UI类4、插件元信息中添加widget键值对,指示插件UI嵌入主界面中的位置5、主界面中预留接入点tabWidget6、插件管理器中元数据…...

一些关于linux process 和python process的记录

python mulprocess 主要用来生成另一个进程并运行 def func(i):print(helloworld)from multiprocessing import Process p Process(targetfunc,args(i, )) p.start()如果想要调用shell命令,可以采用os.popen 或者是 subprocess.run 但是前者只能执行命令并获取输…...

卡尔曼滤波——一种基于滤波的时序状态估计方法

文章目录1. Kalman滤波及其应用2. Kalman原理公式推导:Step 1:模型建立Step 2:开始Kalman滤波Step 3:迭代滤波本文是对 How a Kalman filter works, in pictures一文学习笔记,主要是提炼核心知识,方便作者快…...

什么是X6CrMo17-1

X6CrMo17-1X6CrMo17-1是在430的基礎上加入了鉬,提高鋼的耐點蝕、耐縫隙腐蝕性及強度等,比430鋼抗鹽溶液體性強。一、X6CrMo17-1對應牌號:1、國標GB-T標準:數字牌號:S11790、新牌號:10Cr17Mo、舊牌號&#x…...

软件测试是个人就能做?恕我直言,你可能是个“纯粹”的测试工具人,BUG收集器

作为过来人的我和你说说软件测试的真正情况。 前言 一个软件做出来,最不能少的是谁?毫无疑问是开发,开发是最了解软件运作的那个人,早期就有不少一人撸网站或者APP的例子,相当于一个人同时是产品、研发、测试、运维等…...

递归算法(recursion algorithm)

递归算法 什么是递归算法 在过程或者函数里调用自身的算法; 递归算法(recursion algorithm),通过重复将问题分解为同类的子问题而解决问题的方法, Java中函数可以通过调用自身来进行递归,大多数编程语句…...

VScode下 ESP32 下载程序

ESP32-S3 下载方式可以通过UART0 下载,USB 下载,JTAG下载,还可以使用WIFI进行远程OTA升级程序。插件底栏按键介绍:①选择串口端口号,如COM3; ②选择芯片型号; ③工程idf设置,相当于menuconfig; …...

黑苹果日历

黑果日历 2023/2/27 总结 安装流程 制作启动U盘2017年,本来去当兵,结果近视👓没验上。父母我还想学什么?我想到了黑客操作电脑的画面,感觉特别酷。 2017年有了第一台自己的笔记本,是小米游戏本&#xff0…...

python+pytest接口自动化框架(5)-requests发送post请求

在HTTP协议中,与get请求把请求参数直接放在url中不同,post请求的请求数据需通过消息主体(request body)中传递。且协议中并没有规定post请求的请求数据必须使用什么样的编码方式,所以其请求数据可以有不同的编码方式,服务端通过请…...

Linux 进程:进程控制

目录一、进程创建1.fork2.vfork二、进程终止三、进程等待四、进程替换1.理解程序替换2.子进程在程序替换中的作用Linux的进程控制分为四部分: 进程创建进程终止进程等待进程替换 一、进程创建 常见的创建进程的函数有两个: pid_t fork(void)pid_t vf…...

过滤器的创建和执行顺序

过滤器的创建和执行顺序 8.1.1创建并配置过滤器 P143 重点是如何创建并配置(xml) 1.创建 public class EncodingFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFil…...

JDK1.8 ConcurrentHashMap

数据结构锁sizeCtlconcurrencyLevelForwardingNode、ReservationNode扩容get、put、removehashmap:线程不安全 hashtable:通过synchronized保证线程安全但效率低。强一致性 ConcurrentHashMap:弱一致性 数据结构 ConcurrentHashMap为node数…...

参考 Promise/A+ 规范和测试用例手写 Promise

前言 这可能是手写promise较清晰的文章之一。 由浅至深逐步分析了原生测试用例,以及相关Promise/A规范。阅读上推荐以疑问章节为切入重点,对比Promise/A规范与ECMAScript规范的内在区别与联系,确定怎样构建异步任务和创建promise实例。然后开…...

yolov5数据集制作

yolov5 数据集的格式 每个图像的标注信息存储在一个独立的txt文件中每个txt文件的名称应该与其对应的图像名称相同,只是文件扩展名不同。例如: 对于名为“image1.jpg”的图像,其标注信息应存储在名为“image1.txt”的txt文件中。 在每个txt文件中,每一行表示一个对象的标注…...

主板EC程序烧写异常致无法点亮修复经验

主板型号:Gigabyte AB350M-Gaming3 官网上明确写着支持R5 5500,但按照如下步骤实践下来实际是不支持的 升级biosF31到F40版本的注意事项: 步骤: 1 使用Q-Flash先将bios升级到f31版本;2 然后下载提示中的ECFW Update To…...

【Java爬取赛事网站】命令行输出(仅供学习)

Java爬取赛事网站 Java爬取赛事网站Java爬取赛事网站参与社区的问题回答Gitcode项目地址PSP表格解题思路描述问题接口设计和实现过程编写中的测试关键代码展示性能改进单元测试异常处理心路历程与收获参与社区的问题回答 问题回答这个作业属于哪个课程软件工程-23年春季学期这…...

MongoDB开发者必备:Dbeaver旗舰版的地理空间数据操作全攻略

MongoDB开发者必备:Dbeaver旗舰版的地理空间数据操作全攻略 在位置服务(LBS)应用爆发的时代,地理空间数据处理能力已成为开发者核心技能。无论是共享经济中的车辆调度,还是电商平台的附近推荐,精准的地理查询直接影响用户体验。作…...

双阶段目标检测是什么?有什么用?

一、引言在计算机视觉技术飞速发展的当下,目标检测作为核心分支,早已从实验室走向现实生活的方方面面,成为人工智能感知世界的关键入口。所谓目标检测,就是让计算机通过对图像、视频的分析,同步完成物体定位与物体分类…...

你好吗吗吗吗吗

我真好...

3种方法永久保存QQ空间历史说说:GetQzonehistory实战指南

3种方法永久保存QQ空间历史说说:GetQzonehistory实战指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 为什么需要GetQzonehistory:三个真实场景 想象一下&am…...

自动驾驶之心实习生招募|上海线下,一起做点真东西

点击下方卡片,关注“自动驾驶之心”公众号 戳我-> 领取自动驾驶近30个方向学习路线 自动驾驶之心是业内头部的垂类自媒体平台,过去一年,我们梳理了端到端、VLA、世界模型、强化学习等前沿方向的最新进展,也分享了行业概况、融资…...

Android10音频系统实战:如何自定义音量曲线(附default_volume_tables.xml修改指南)

Android 10音频系统深度定制:音量曲线调优实战手册 在移动设备音频体验的精细打磨中,音量曲线的定制往往是最容易被忽视却至关重要的环节。作为一名长期从事Android系统定制的开发者,我曾为多款旗舰设备调整过音频参数,发现原厂音…...

OV5640摄像头SCCB配置详解:告别照抄寄存器表,教你读懂数据手册进行个性化设置

OV5640摄像头SCCB高级配置实战:从寄存器表解读到图像优化全解析 1. 深入理解OV5640寄存器架构 OV5640作为OmniVision推出的500万像素图像传感器,其强大功能背后是超过200个可配置寄存器。许多开发者习惯直接套用现成的寄存器配置表,但当遇到图…...

async-http-client原生镜像大小优化:GraalVM裁剪终极指南 [特殊字符]

async-http-client原生镜像大小优化:GraalVM裁剪终极指南 🚀 【免费下载链接】async-http-client Asynchronous Http and WebSocket Client library for Java 项目地址: https://gitcode.com/gh_mirrors/as/async-http-client 在当今云原生和微服…...

Qwen3-ASR-1.7B开源ASR教程:适配国产昇腾/寒武纪平台的移植可行性分析

Qwen3-ASR-1.7B开源ASR教程:适配国产昇腾/寒武纪平台的移植可行性分析 1. 项目背景与模型介绍 「清音听真」是基于Qwen3-ASR-1.7B语音识别引擎的高精度转录平台。作为0.6B版本的跨代升级,这个1.7B参数的模型在复杂语音场景处理能力上实现了显著提升。 …...

自动驾驶轨迹预测新思路:VectorNet如何用矢量编码替代传统栅格化方法?

自动驾驶轨迹预测的矢量革命:VectorNet如何重构环境编码范式 在自动驾驶系统的决策闭环中,轨迹预测模块犹如驾驶员的预判能力,其准确性直接关系到行车安全与舒适性。传统基于卷积神经网络(CNN)的预测方法存在一个根本性…...