uio是什么意思

uio是什么意思,第1张

UIO的意思如下:

UIO(Userspace IO)是运行在用户空间的IO技术。Linux系统中一般的驱动设备都是运行在内核空间,而在用户空间用应用程序调用即可,而UIO则是将驱动的很少一部分运行在内核空间,而在用户空间实现驱动的绝大多数功能,使用UIO可以避免设备的驱动程序需要随着内核的更新而更新的问题。

工作原理:

UIO在用户空间下的驱动程序比运行在内核空间的驱动要多得多,UIO框架下运行在内核空间的驱动程序所做的工作很简单,常做的只有两个:分配和记录。设备需要的资源和注册UIO设备和,必须在内核空间,实现的小部分中断应答函数。

UIO内核空间的程序所做的越少越好,在用户空间能完成的,就不需要放在内核空间做(比如说响应中断),这样假如内核有变化,UIO框架中的驱动维护也是比较简单的。对于用户空间的驱动程序,还可以集成到某款应用软件中。因为使用UIO的设备一般比较少见,所以,可以作出这类的驱动,也可以针对某款或者一类设备作出应用程序集成驱动即可。

本文整理下之前的学习笔记,基于DPDK17.11版本源码分析。主要分析一下igb_uio驱动源码。

首先简单介绍一下kernel中的总线-设备-驱动模型,以pci总线为例,pci总线上有两个表,一个用于保存系统中的pci设备,一个用于保存pci设备对应的驱动。每当加载pci设备驱动时,就会遍历pci总线上的pci设备进行匹配,每当插入pci设备到系统中时,热插拔机制就会自动遍历pci总线上的pci设备驱动进行匹配,如果匹配成功则使用此驱动初始化设备。

注册pci总线

可以调用bus_register注册总线。比如下面的pci总线,平台总线和usb总线等。

注册总线后,会在 /sys/bus 下生成总线目录,比如 pci 总线会生成目录 /sys/bus/pci

注册总线后,会生成文件/sys/bus/pci/drivers_autoprobe,写此文件时在kernel中会调用如下函数,如果为1,表示 bus 支持自动探测 device,则加载驱动时,自动遍历所有pci设备进行匹配

注册驱动到pci总线

结构体struct pci_driver表示一个pci设备驱动,其中id_table和dynids用来保存此驱动支持的设备id等信息,如果有匹配的设备,则调用probe函数。

调用函数pci_register_driver注册pci设备驱动。

注册驱动后,会在/sys/bus/pci/drivers目录下创建以驱动名字命名的目录,并在此目录下创建new_id, bind和unbind等sys文件,可以通过这些文件动态修改驱动信息。

向new_id写入"0x0806 0x1521"信息(0x0806表示vendor id,0x1521为device id)时,会调用kernel中的store_new_id,解析相关字段后,保存到动态链表dynids,然后遍历当前所有的pci设备进行匹配。

向bind文件写入网卡的pci地址时,会调用kernel中的bind_store,将此网卡绑定到此驱动。

向unbind文件写入网卡的pci地址时,会调用kernel中的unbind_store,将此网卡和此驱动解绑。

发现pci设备

系统启动时会扫描所有的pci设备,以他们的pci地址为名字创建目录,并在此目录下创建相关的sys文件。并且会遍历所有的pci设备驱动进行匹配。

向设备的driver_override文件写入驱动名字,表示此设备只能绑定到此驱动。

如何匹配?

前面多次提到设备和驱动进行匹配,究竟如何匹配呢?

先看一下用来表示一个pci设备的结构体pci_dev,其中如下几个成员变量表示此pci设备的类型,一般vendor和device就足够,vendor表示此设备是哪个厂商的,device表示此设备的类型。

再看一下用来表示设备驱动的pci_driver,其中id_table和dynids用来保存此驱动支持的设备类型,前者是静态值,后者可以通过驱动目录下的new_id动态添加。设备类型使用pci_device_id结构体来表示,其成员变量也是vendor,device等信息,和pci_dev中的信息是一样的,所以可以使用这几个字段进行匹配。

最终使用函数pci_match_device进行驱动和设备的匹配。

网卡如何绑定到igb_uio驱动呢?这里拿DPDK提供的脚步文件dpdk-devbind.py中的函数bind_one进行分析。

igb_uio驱动的id_table为空,则在加载此驱动时,是不会匹配到任何设备的。

经过上面的分析,有三种方法可以将网卡绑定到驱动igb_uio

igb_uio probe

经过前面的分析网卡绑定到了igb_uio驱动后,会调用驱动的probe函数igbuio_pci_probe,主要做了如下几个事情:

a. 调用pci_enable_device使能pci设备

b. 设置DMA mask

c. 填充struct uio_info信息,注册uio设备

d. 注册中断处理函数

宏uio_register_device用来注册uio设备。

简单总结一下,igb_uio是DPDK使用网卡的一个通用驱动,不只intel网卡可以用,其他厂商的网卡也可以用(有一个例外,mellanox的网卡不用绑定到igb_uio就能被使用DPDK),因为它只使能了pci设备,注册uio,和注册中断处理函数,这些工作是不区分网卡类型的。

加载igb_uio时,不会自动探测pci设备,而是需要写sys文件将设备绑定到igb_uio。

igb_uio依赖uio驱动,注册uio设备后,会生成/dev/uiox,和网卡一一对应,用户态可以poll /dev/uiox监听中断是否到来。

同时uio设备还会将网卡的BAR地址通过sys文件系统暴露出去,用户态可以mmap sys文件后 *** 作网卡寄存器。但是DPDK没有采用这种方式,而是直接mmap网卡自身暴露出去的sys文件 /sys/bus/pci/devices/'pci address'/resource0。

https://www.cnblogs.com/jungle1996/p/12398915.html

https://www.cnblogs.com/jungle1996/p/12452636.html


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12166953.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存