PCI设备与UIO驱动

news2025/7/14 8:24:14

随着网络的高速发展,对网络的性能要求也越来越高,DPDK框架是目前的一种加速网络IO的解决方案之一,也是最为流行的一套方案。DPDK通过bypass内核协议栈与内核驱动,将驱动的工作从内核态移至用户态,并利用polling mode的线程工作模式加速网络I/O使得网络IO性能出现大幅度的增长。

  在使用DPDK的时候,我们常常会说提到用DPDK来接管网卡以达到bypass内核驱动以及内核协议栈的操作,本篇文章将主要分析DPDK是如何实现的bypass内核驱动来实现所谓的“接管网卡”的功能。

注意:

  1. 本篇文章会涉及一些pci设备的内容,但是不会重点讲解pci设备,pci设备中的某些规则就是这么设计的,并没有具体原因。
  2. 本篇部分原理的讲解会以Q&A的方式拖出,因为DPDK bypass内核的这部分涉及的知识维度比较多,没有办法按照线性的思路讲解。
  3. 本人能力以及水平有限,没办法保证没有疏漏原创内容
  4. 由于内容过多,本篇文章会着重基础的将PCI以及igb_uio相关的知识与分析,以便于不光是从DPDK本身,而是全面的了解DPDK如果做到的bypass内核驱动,另外关于DPDK的代码部分实现将会放在后续文章中放出,另外还有DPDK的中断模式以及vfio也会在后续的文章中依次发出(先开个坑,立个flag)

【1.谈一谈使用】

  通常启动一个基于dpdk开发的应用,都需要几步准备来完成。

  1. 首先需要插入igb_uio/vfio-pci这两个驱动中的一个,接下来会以igb_uio为例讲解(因为简单...vfio还是有点复杂的...vfio的解析会放在以后的文章中放出)。
  2. 其次需要运行dpdk-devbinds.py这个dpdk官方给出的py脚本,以此来完成内核驱动到igb_uio/vfio的接管。接管之后,再次运行dpdk-devbinds可以很明显的看到驱动从ixgbe转为了igb_uio。请见图1.
  3. 运行dpdk应用,以-p参数指定要接管的网口,例如-c 0x03,那么接管的网口便是port 0和port 1.

图1.接管前后pci设备驱动发生的变化

  那么经过上述三个操作,至少脑子里会产生这么几个问题:

  Q:igb_uio/vfio-pci的作用是什么?为什么要用这两个驱动?这里的“驱动”和dpdk内部对网卡的“驱动”(dpdk/driver/)有什么区别呢?

  Q:dpdk-devbinds是如何做到的将内核驱动解绑后绑定新的驱动呢?

  Q:dpdk应用内部是如何操作pci设备的呢?是怎么让pci设备可以将数据包直接扔到用户态的呢?

  这三个问题,实际上也是我当初在研究这一部分是遇到的三个问题。首先我们先来看第一个问题。

【问题一:igb_uio/vfio-pci是什么?】

  我们会以igb_uio驱动为例进行讲解。这里其实很难一步讲清楚igb_uio的作用以及实现原理,所以接下来的讲解还是会以Q&A和“挖坑式”的方式进行逐步将原理展现给各位看官面前。先说说操作一个外设,最先想到的是什么呢?如果有过单片机等嵌入式外设开发的朋友肯定会冒出这样的一个想法

我得配置这个外设,为此我需要找到它的寄存器,但是找到它的寄存器前提是我得先拿到基地址才行, 接下来通过基地址+寄存器偏移就能找到寄存器所在的地址,然后就可以配置了

  所以第一个任务便是我们要拿到”基地址“,首先有必要先科普一下pci设备的基地址。因此我必须得掏出一张图,即描述pci配置空间的一张图,如果图2所示。

图2.pci设备的配置空间

  图2为pci配置空间的分布图,在图中,0x0010 ~ 0x0028这24个字节中,分布着6个PCI BAR(base address register),也就是最最重要的“基地址”,那这里有人可能会想问“这个图和我们有关系么?这个图中的空间在哪?我们该怎么解析?”,答案是“无关”,这些图中的信息事实上在系统启动时,就已经被解析完成了,以文件系统的方式供用户态程序取读取。但是这里其实有这样的一个问题:

PCI设备为啥有6个BAR,而不是3个、8个?这些BAR都有啥区别?实际访问寄存器的时候以哪一个BAR为基准呢?

  其实解释这个问题,是一件简单而又不简单的事情。简单是因为pci设备规定就是有6个bar空间,而不简单是因为不知道为什么规定6个bar空间。那么这些BAR又有什么区别呢?这里要引用一下stackoverflow上面一位老哥说的话,见图3.(这里其实我之前也一直不太明白,因为国内的很多论坛帖子都是千篇一律...很难筛选出自己想要的信息...)

图3.不同BAR空间的区别之StackOverflow

  其实关键就是蓝色的那句话,即”6个槽(BAR)允许设备以不同的目的提供不同的区域“,根据这个线索,我们来看一下intel 82599这款经典的10G网卡的datasheet中9.3.6中的解释。见图4.

图4.intel 82599 datasheet中关于不同pci bar的划分

  可以看到这款经典网卡(其实intel的卡基本都是这么分的)主要将6个pci bar分成了三块区域:

  • Memory BAR : 内存BAR,Memory BAR标志着这块BAR空间位于内存空间,通过mmap映射后可以直接访问。
  • I/O BAR : IO BAR空间,I/O BAR标志着这块BAR空间位于IO空间,对其的访问不能像Memory BAR那样映射之后就可以随心所欲访问,IO BAR必须通过专门的操作来进行读写。
  • MSI-X BAR : 这个BAR空间主要是用来配置MSI -X 中断向量。

  那么这里可能有人会问,一共不是6个BAR空间么?这里只分了3个区域,那么每个区域分多少呢?这里请注意的是关于图3中6个PCI BAR,每个PCI BAR都是32位的,但是像82599这种工作在64位的网卡,其实就只有三个BAR。BAR0 BAR1为Memory BAR,BAR2 BAR3为I/O BAR,BAR4 BAR5为MSI-X BAR。这里我们可以对照一款低端网卡I350的datasheet,见图5.

图6.I350网卡datasheet中关于BAR分布的描述

   从图6可以看到,对于I350这种低端的千兆网卡,可以将其配置位工作在32位还是64位模式下,但是对于82599这种万兆10g的卡,就没那么多选择余地了,只能工作在64位模式下,因此回到图3中,我们可以根据intel 82599的datasheet来得知intel的64bit网卡的bar分布是长什么样子的,如图7.

图7.intel 82599网卡的BAR分布

  所以PCI配置空间的规范结合intel的I350和82599这两款网卡的datasheet进行分析,我们可以得出这样的一个结论:”PCI有6个BAR是规范,6个BAR的区别和作用取决于具体的PCI外设,需要查看datasheet才能给出答案“。

  说完6个BAR的作用以及分布,接下来还有个问题,实际访问PCI BAR的时候以哪一个BAR为基准呢?这里主要有疑问的地方会出现在Memory BAR还是I/O BAR。因为需要搞清楚这两者的区别,才能真正判断在哪个BAR写配置。关于IO BAR和Memory BAR的区别首先需要科普一下,在x86体系架构下,内存的编址情况。接下来进入科普时间。

  其实这里是比较晦涩难懂的,首先我们得知道,为什么会出现I/O空间和外设空间?在讨论区别之前我们可以看一张图,看看I/O空间和Memory空间长什么样子,这里可以看宝华叔经典的《Linux设备驱动开发详解》的第11章部分,这里我就简单的说一下,x86下的I/O空间和Memory空间到底长啥样子。见图8.

图8.I/O空间与内存空间,来自宝华叔的《Linux设备驱动开发详解》中第11章

  另外需要注意的时,非x86体系架构下,例如ARM、PowerPC这些架构下,所有的外设和主存(RAM)都会进行统一的编址,所以kernel可以像访问正常的内存空间一样访问内设。而x86体系架构下,外设是进行独立编址的,如图8所示,因此也就出现了IO空间和Memory空间的区别。(其实可以将RAM看成一种”专门用来内存映射的IO设备“)。另外我们从图8还可一看到另外一个信息,那

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tuxera NTFS2024最新永久版下载和安装

要使用Tuxera NTFS for Mac,你需要先下载和安装Tuxera NTFS for Mac驱动器,然后按照以下步骤操作: 1、下载和安装Tuxera NTFS for Mac 免费下载Tuxera NTFS for Mac驱动器的最新版本。下载完成后,双击DMG文件并按照提示安装即可…

攀岩安全带,儿童攀岩安全带合规标准是什么?如何办理?

攀岩安全带 本政策适用于主要用于攀岩或登山活动的安全带。攀岩安全带是一种装备,可穿戴在攀岩者或登山者的腰部和大腿处。攀岩安全带为绳子提供了一个连接点,并提供一种手段,以便在攀登、休息、绕绳下降或跌落的过程中为攀登者身体提供支撑…

2023年10月wxid转微信号方法

在9月份tx做了一次调整,以前很多wxid转微信号的办法都失效了。 今天分析了一下微信。捣鼓了一下午。现在已经实现了wxid转微信号。不管对方是否在群里,是否是你的好友 都能转。一分钟出60条左右。 我们先创建一个文本文件,将要转换wxid 放进…

Vue2使用定时器和闭包实现防抖和节流函数。将函数放入util.js中,供具体功能在methods中调用

Vue2使用定时器和闭包实现防抖和节流函数。将函数放入util.js中&#xff0c;供具体功能在methods中调用。<br/ 参考文档&#xff1a; 如何在Vue中优雅的使用防抖节流人类高质量JS防抖与节流机制Vue项目中使用防抖和节流vue2使用lodash中的防抖&#xff08;debounce&#xff…

现货黄金操作建议

如果您想得到更好的现货黄金操作建议&#xff0c;那就应该读读Jack Schwager的经典交易著作是《市场奇才&#xff1a;顶级交易者访谈》。这本书1989年首次出版&#xff0c;当中收录了对美国一些传奇交易者的访谈&#xff0c;当中的一些建议不但有用&#xff0c;而且经得起的时间…

Win10更新错误代码0x800f081f的解决方法

在Win10电脑中&#xff0c;用户点击更新系统版本&#xff0c;却遇到了更新错误的情况&#xff0c;还有0x800f081f错误提示。如果出现这样的情况&#xff0c;用户就无法正常完成Win10系统的更新了&#xff0c;接下来小编给大家介绍两种简单有效的解决方法&#xff0c;解决后大家…

WebGPU入门一

1 WebGPU学习开发环境配置 WebGPU的环境配置比较简单&#xff0c;不需要vite或webpack配置一个复杂的开发环境&#xff0c;直接使用.html文件即可。 1.1 支持WebGPU的浏览器 Chrome 113 beta测试版开始默认支持WebGPU。 1.2 index.html文件 创建index.html文件&#xff0c…

uni-app:对数组对象进行以具体某一项的分类处理

一、原始数据 这里定义为五个数组&#xff0c;种类product有aaa,bbb两种 原始数据在data中进行定义 res: {"success": true,"devices": [{no: 0,product: aaa,alias: "设备1",assign: [["a1", "a2", "a3"],[&q…

论文解析-moETM

论文解析-moETM 参考亮点动机发展现状现存问题 功能方法Encoder改进Decoder改进 评价指标生物保守性批次效应移除 实验设置结果多组学数据整合cell-topic mixture可解释性组学翻译性能评估RNA转录本、表面蛋白、染色质可及域调控关系研究1. 验证同一主题下&#xff0c;top gene…

Python武器库开发-基础篇(二)

基础篇(二) if 语句 编程时经常需要检查一系列条件&#xff0c;并据此决定采取什么措施。在Python中&#xff0c;if 语句让你能够检查程序的当前状态&#xff0c;并据此采取相应的措施 下面是一个简短的示例&#xff0c;演示了如何使用if 语句来正确地处理特殊情形。假设你有…

cmd进程简单操作指令

dir 查询当前路径和子路径 start空格加自己的exe程序&#xff0c;可运行程序。 taskkill /?可以执行很多&#xff0c;通常用于结束程序。 taskkill /f /im qq.exe 启动nginx.exe 查看运行的进程有哪些 选择结束nginx.exe

手写一个PrattParser基本运算解析器3: 基于Swift的PrattParser的项目概述

点击查看 基于Swift的PrattParser项目 PrattParser项目概述 前段时间一直想着手恶补 编译原理 的相关知识, 一开始打算直接读大学的 编译原理, 虽然内容丰富, 但是着实抽象难懂. 无意间看到B站的熊爷关于普拉特解析器相关内容, 感觉是一个非常好的切入点.所以就写了基于Swift版…

试着写几个opencv的程序

一、认识opencv OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源计算机视觉库&#xff0c;旨在提供丰富的图像处理和计算机视觉功能&#xff0c;以帮助开发者构建视觉应用程序。OpenCV最初由英特尔开发&#xff0c;现在由社区维护和支持。它支持…

【Javascript保姆级教程】显示类型转换和隐式类型转换

文章目录 前言一、显式类型转换1.1 字符串转换1.2 数字转换1.3 布尔值转换 二、隐式类型转换2.1 数字与字符串相加2.2 布尔值与数字相乘 总结 前言 JavaScript是一种灵活的动态类型语言&#xff0c;这意味着变量的数据类型可以在运行时自动转换&#xff0c;或者通过显式类型转…

Vue3使用Vite创建项目

node版本&#xff1a;node -v v18.16.0 npm版本: npm -v 9.5.1 Vite Vite&#xff1a;是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验 脚手架&#xff0c;创建Vue项目&#xff0c;替代 Vue-cli 基于Vite创建vue项目&#xff1a; 1.npm create vitelatest 2.完…

只要封装相同,电容体本身大小就一样吗?

高速先生成员--黄刚 当然这篇文章也还是针对高速信号的交流耦合电容&#xff0c;并不是用于电源的去耦电容&#xff0c;同时文章的灵感也来源于上一篇文章讲不同容值电容对高速信号原理上的效果差异。为什么我们在做高速设计的时候&#xff0c;速率越高&#xff0c;希望电容封装…

硬件小白,如何在有限的预算里选择一款性价比最高的硬盘?

硬件小白&#xff0c;如何在有限的预算里选择一款性价比较高的硬盘 明确使用场景三大种类SSD、HHD、HDDSSD 固态硬盘&#xff08;Solid State Drive&#xff09;HHD 混合硬盘&#xff08;Hybrid Hard Drive)HDD 传统硬盘&#xff08;Hard Disk Drive&#xff09;小结 重要参数机…

3分钟了解 egg.js

Eggjs是什么&#xff1f; Eggjs是一个基于Koajs的框架&#xff0c;所以它应当属于框架之上的框架&#xff0c;它继承了Koajs的高性能优点&#xff0c;同时又加入了一些约束与开发规范&#xff0c;来规避Koajs框架本身的开发自由度太高的问题。 Koajs是一个nodejs中比较基层的…

MFC-列表控件

目录 1、更改列表控件的属性&#xff1a; 2、代码设置表头&#xff1a; 3、设置正文内容&#xff1a; 4、设置属性&#xff0c;显示成表格形式 &#xff1a; 5、代码实现&#xff1a; 1、更改列表控件的属性&#xff1a; VIEW设置为Report模式会出现表格形状 2、代码设置…