用户态驱动的两种方式-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年有了第一台自己的笔记本,是小米游戏本࿰…...
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年春季学期这…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
