character device
TRANSCRIPT
北京大学微处理器研究开发中心
Contents
Linux设备管理及设备分类简介字符设备及其特点字符设备驱动基本特性要求从一个具体的字符设备驱动scull来看字符设备驱动设计要求字符设备驱动设计的一些具体问题简介References
北京大学微处理器研究开发中心
Linux系统中设备管理特点
沿用UNIX系统的设备文件概念,设备与文件有一致的用户接口主要设备文件在/dev目录中分类–
字符设备(Character Device)
–
块设备(Block Device)–
* 网络设备(Network Device)
北京大学微处理器研究开发中心
Linux设备文件分类
字符设备(Character Device)–
以字节流(byte stream)方式存取,不能随机访问–
内核对其无缓冲机制
块设备(Block Device)–
可支持随机存取,以块(block)为单位进行存取–
内核提供缓冲机制
* 网络设备(Network Device)–
网络传输的软件抽象接口,以data packet为单位进行存取–
一般不以设备文件形式存在,由系统单独统一命名,如eth0
北京大学微处理器研究开发中心
设备文件实例
字符设备(Character Device)–
字符终端(/dev/tty[x]、/dev/console)–
串行接口(/dev/ttyS0)
块设备(Block Device)–
各种硬盘、光驱等(/dev/hd[x]、/dev/sd[x]…、/dev/cdrom)–
Ram Disk(/dev/ram[x])
网络设备(Network Device)–
eth[x] –
wlan[x]
北京大学微处理器研究开发中心
字符设备(Character Device)
支持面向字节流的读写(stream-oriented)与普通文件的区别–
普通文件:一般都支持向前、向后移动读写位置
–
字符设备文件:大多不支持向前、向后移动读写位 置,不过也有少数例外
其字节流读写特性由字符驱动(char driver)实现支持
北京大学微处理器研究开发中心
字符设备的特点
结构相对块设备(Block Device)简单很多,无需考虑内核的缓冲机制对I/O存取过程中产生的影响可以用现成的处理普通文件的方法来处理,通用性强使用广泛,很多设备均以字符设备文件的形式工作
北京大学微处理器研究开发中心
字符设备驱动(Character Driver)
字符驱动(Char driver)需至少实现如下系统调用(System Call)以满足对字符设备文件的基本操作:–
open
–
close–
read
–
write
北京大学微处理器研究开发中心
字符设备驱动(Character Driver)
特点–
如同字符设备,相对块设备驱动和网络设备驱动等
其它驱动来说,结构简单,易于理解–
概念适用于大多数简单字符设备驱动
–
适合于初学及入门
典型实例–
scull (Simple Character Utility for Loading Localities)
北京大学微处理器研究开发中心
scull
一个基于某一内存区域实现字符设备的驱动特点–
Hardware independent,不依赖于独特的硬件,仅
仅需要一块内核分配的内存空间–
一般仅用来示范内核与字符驱动之间的接口,以及
提供给用户一个测试的对象,对于现实的硬件没有 有效的意义
–
对于学习Linux驱动来说,scull是一个很好的切入 点
北京大学微处理器研究开发中心
从scull看驱动设计
驱动程序的机制设计——提供用户程序接口scull驱动实现的设备–
scull0 –
scull3 : each consisting of a memory
area that is both global
and persistent–
scullpipe0 –
scullpipe3 : FIFO devices, work like
pipes–
scullsingle : allow only one process to use at a time
北京大学微处理器研究开发中心
从scull看驱动设计
scull驱动实现的设备–
scullpriv : private to each virtual console, different memory area assigned
–
sculluid/scullwuid : can be opened multiple times, but only by one user at a time.
北京大学微处理器研究开发中心
设备的Major number 和
Minor number
Major number : identifies the driver associated with the deviceMinor number : used by the kernel to determine exactly which device is being referred to.Linux 内核使用dev_t类型来表示major number(12 bits)和minor number(20 bits)
北京大学微处理器研究开发中心
Device Number 的分配和释放
使用register_chrdev_regionregister_chrdev_region函数来获得指定的Device Number
–
需确定指定的Device Number尚未被占用,否则出错
使用alloc_chrdev_regionalloc_chrdev_region函数来从内核获得一个当前可用的Device Number使用unregister_chrdev_regionunregister_chrdev_region来释放当前被占用的Device Number详见LDD 3rd P45
北京大学微处理器研究开发中心
涉及的3个内核基本数据结构
file_operations–
对于特定文件,提供指向对应的文件操作的函数指
针等
file–
用来表示一个打开的文件,由内核创建并传递给操
作文件的函数
inode–
内核内部用于表示文件的结构
北京大学微处理器研究开发中心
字符设备的注册(Registration)与删除 (Removal)
内核内部使用cdevcdev结构体来表示字符设备,需包含头文件<linux/cdev.h>使用cdev_alloccdev_alloc函数来请求内核分配字符设备相应资源,并返回指向新设备的cdev结构的指针(也可以使用cdev_initcdev_init来给自己维护来给自己维护的的cdevcdev结构分配相应字符设备资源结构分配相应字符设备资源))使用cdev_delcdev_del函数来删除给定的cdev结构指针所代表的字符设备,释放相应资源
北京大学微处理器研究开发中心
必须实现的四个基本方法(Method)
前面提到为了使字符设备驱动正常工作,至少需要提供四个基本的系统调用,以满足最基础的设备的使用需求–
open Method
–
release/close Method–
read Method
–
write Method
北京大学微处理器研究开发中心
open Method
提供初始化操作,为后面提供设备操作做准备需要完成以下工作–
检查设备错误
–
如果设备首次打开,进行设备初始化–
更新file_operations结构体指针
–
分配并更新file结构体中private_data成员中的 所有数据结构
北京大学微处理器研究开发中心
release Method
执行与open Method相反的操作,释放设备占用的相应资源和数据结构需要完成的任务–
释放所有file结构体的private_data中由open Method申请的数据结构资源
–
如果是最后一个释放操作,则关闭相应的设备
北京大学微处理器研究开发中心
read&write
Method
两者执行的操作非常相似,均是在程序代码之间复制数据,因此两者的实现也很相似,提供接口也大致相同特殊的“版本”:readv&writev,提供对一个操作对象的结构体集合一次性进行操作。如果没有专门提供,可以借用多次调用read&writeMethod来实现