聊聊Linux用户态驱动设计
序言
设备驱动可以运行在内核态,也可以运行在用户态,用户态驱动的利弊网上有很多的讨论,而且有些还上升到政治性上,这里不再多做讨论。不管用户态驱动还是内核态驱动,他们都有各自的缺点。内核态驱动的问题是:系统调用开销大;学习曲线陡峭;接口稳定性差;调试困难;bug致命;编程语言选择受限;而用户态驱动面临的挑战是:如何中断处理;如何DMA;如何管理设备的依赖关系;无法使用内核服务等。对此,《User-Space Device Drivers in Linux: A First Look》 一文有较详细描述。
可能是为了性能优化,或者为了故障隔离,或者为了逃避开源许可证的约束,不管是基于何种目的,linux已有多种用户态驱动的实现,如UIO,VFIO、USB用户态驱动等。它们在处理中断、DMA、设备依赖管理等方面的设计方案和实现细节上各有千秋,这是《User-Space Device Drivers in Linux: A First Look》 没有提到的,也是本文的重点。
UIO
UIO 框架导出sysfs和/dev/uioX 2套用户态接口,用户对设备节点/dev/uioX进行设备控制,mmap()接口用于映射设备寄存器空间,write()接口用于控制中断关闭/打开,read()接口用于等待一个设备中断。
因为对于设备中断的应答必须在内核空间进行,所以在内核空间有一小部分代码用来应答中断和禁止中断,其余的工作全部留给用户空间处理。如果用户空间要等待一个设备中断,它只需要简单的阻塞在对 /dev/uioX的read()操作上。 当设备产生中断时,read()操作立即返回。UIO 也实现了poll()系统调用,你可以使用 select()来等待中断的发生。select()有一个超时参数可以用来实现有限时间内等待中断。
UIO的几个特点:
- 一个UIO设备最多支持5个mem和portio空间mmap映射。
- UIO设备的中断用户态通信机制基于wait_queue实现。
- 一个UIO设备只支持一个中断号注册,支持中断共享。
总的来说,UIO框架适用于简单设备的驱动,因为它不支持DMA,不能支持多个中断线,缺乏逻辑设备抽象能力。
VFIO
上文提到,UIO不支持DMA,所以通过DMA传输大流量数据的IO设备,如网卡、显卡等设备,无法使用UIO框架,VFIO做为UIO的升级版,主要就是解决了这个问题。通过用户态配置IOMMU接口,可以将DMA地址空间映射限制在进程虚拟空间中。这对高性能驱动和虚拟化场景device passthrough尤其重要。
在VFIO框架中,有几个核心概念或对象:IOMMU、/dev/vfio、container、iommu_group。
- IOMMU是一个硬件单元,它可以把设备的IO地址映射成虚拟地址,为设备提供页表映射,设备通过IOMMU将数据直接DMA写到用户空间。之所以不共用MMU单元,是为了保证和进程的页表相互独立,防止设备访问进程的任意地址空间。所以VFIO的IOMMU功能保障了安全的非特权级别的用户态设备驱动机制。
- /dev/vfio是一个设备文件,作为一个IOMMU设备的用户态呈现。
- container是内核对象,表示一个IOMMU设备,是一个IOMMU设备的内核态呈现。所以在VFIO中,container是IOMMU操作的最小对象。
- 在虚拟化场景下,一个物理网卡可能要虚拟成几个虚拟网卡,或者说虚拟功能设备(VF),这几个VF共用一个IOMMU,所以VFIO模型增加一个iommu_group的概念,用来表示共享同一个IOMMU的一组device。
VFIO的几个特点:
- VFIO设备支持多中断号注册。
- 设备的中断用户态通信机制基于eventfd/irqfd实现。用户通过/dev/vfio设备select/poll/epoll,从而实现中断从内核态到用户态的异步事件通知。
- 支持对物理设备进行逻辑抽象。
- 仅支持pci intx中断共享,其他类型中断不支持共享。
- VFIO仅支持特定IOMMU设备,如x86与PowerPC平台的PCI设备和ARM平台的platform设备。
USB用户态驱动
usbfs(USB file system)提供了一些在用户空间下操作USB设备的函数接口和数据结构, 在开发用户态驱动时, 可以直接利用这些函数接口来实现对 USB 设备的控制和数据传输。
libusb对usb file system提供的函数接口和数据结构进行了封装, 可以有效减少程序中函数和数据结构使用不当造成的错误。Libusb 对 USB 设备的访问提供了两种机制, 同步访问和异步访问。
khubd是内核后台线程,用来管理监视USB HUB的状态, 一旦发生热插拔就会唤醒这个线程, 进而添加或者移除设备,并发送netlink消息传递给用户态空间。
USB 用户态驱动框架的几个特点:
- 设备的中断用户态通信机制基于netlink实现。
- USB设备以usbdevfs (后改名为usbfs)文件系统的形式(如/proc/bus/usb/BBB/DDD)对用户态呈现。
- 对usb的所有访问通过usbfs ioctl实现,如control transfer, bulk transfer, reset等。
- 仅支持USB设备
参考资料
User-Space Device Drivers in Linux: A First Look
聊聊Linux用户态驱动设计的更多相关文章
- Linux用户态驱动设计
聊聊Linux用户态驱动设计 序言 设备驱动可以运行在内核态,也可以运行在用户态,用户态驱动的利弊网上有很多的讨论,而且有些还上升到政治性上,这里不再多做讨论.不管用户态驱动还是内核态驱动,他们都 ...
- I2C用户态驱动设计
一.用户态驱动模型 1.1 I2C通用驱动代码 i2c_dev_init: static int __init i2c_dev_init(void) { int res; printk(KERN_IN ...
- [国嵌攻略][155][I2C用户态驱动设计]
用户态驱动模型 用户态驱动模型首先是一个应用程序,其次是在这个用户程序中通过内核调用来驱动设备. IIC通用驱动代码 IIC通用驱动程序的代码在/drivers/i2c/i2c-dev.c中.一次读操 ...
- Linux I2C驱动--用户态驱动简单示例
1. Linux内核支持I2C通用设备驱动(用户态驱动:由应用层实现对硬件的控制可以称之为用户态驱动),实现文件位于drivers/i2c/i2c-dev.c,设备文件为/dev/i2c-0 2. I ...
- [中英对照]User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序
如对Linux用户态驱动程序开发有兴趣,请阅读本文,否则请飘过. User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序 ...
- linuxok6410的I2C驱动分析---用户态驱动
3 i2c-dev 3.1 概述 之前在介绍I2C子系统时,提到过使用i2c-dev.c文件在应用程序中实现我们的I2C从设备驱动.不过,它实现的是一个虚拟,临时的i2c_client,随着设备文件 ...
- Linux用户态与内核态通信的几种方式
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Linux 用 ...
- Linux 用户态与内核态的交互【转载】
Linux 用户态与内核态的交互 在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,例如iprote2网络管理工具,它与内核的交 ...
- linux用户态和内核态通信之netlink机制【转】
本文转载自:http://blog.csdn.net/zcabcd123/article/details/8272360 这是一篇学习笔记,主要是对<Linux 系统内核空间与用户空间通信的实现 ...
随机推荐
- Vue中method与computed的区别
为了说明method与computed的区别,在此我想先来看看computed属性在vue官网中的说法:模板内的表达式是非常便利的,但是它们实际上只用于简单的运算.在模板中放入太多的逻辑会让模板过重且 ...
- 在页面加载后在设置embed 的src 怎么实现?
我想在页面加载完之后,再给embed 加入src 值,但embed 后播放不了.下面是我的两个方案,都无法播放,求解: <script type="text/javascript&qu ...
- Python基础学习参考(五):字符串和编码
一.字符串 前面已经介绍过字符串,通过单引号或者双引号表示的一种数据类型.下面就再来进一步的细说一下字符串.字符串是不可变的,当你定义好以后就不能改变它了,可以进一步的说,字符串是一种特殊的元组,元 ...
- 一个可以自由定制外观、支持拖拽消除的MaterialDesign风格Android BadgeView
为了尊重作者,先放上链接:https://github.com/qstumn/BadgeView BadgeView 一个可以自由定制外观.支持拖拽消除的MaterialDesign风格Android ...
- NLP+VS︱深度学习数据集标注工具、方法摘录,欢迎补充~~
~~因为不太会使用opencv.matlab工具,所以在找一些比较简单的工具. . . 一.NLP标注工具BRAT BRAT是一个基于web的文本标注工具,主要用于对文本的结构化标注,用BRAT生成的 ...
- Shell脚本编程学习入门 02
Shell脚本编程学习入门是本文要介绍的内容,我们可以使用任意一种文字编辑器,比如gedit.kedit.emacs.vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行): #! ...
- vxworks下文件读写示例
dev 1.create file on floopy disk and write contents: -> pdev=fdDevCreate(0,0,0,0) /* A:,1.44M ...
- Java兔子问题
题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? /** * @Title:Rabbit.java ...
- phpcmsv9更换模板介绍
先分享下大概的步骤: 1.上传模版文件到服务器:2.在站点管理 里边[模板风格配置]选择新模板:3.设置不同模型对应模板:4.修改现有的栏目,匹配新模板:5.更新栏目缓存.系统缓存,更新HTML静态页 ...
- JXL组件生成报表报错(一)
JXL组件生成报表 1.具体报错如下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonami ...