LINUX DEVICE DRIVER(2ND)第3章 字符设备驱动程序(1,待续)

来源:互联网 发布:辗转相除法的算法框图 编辑:程序博客网 时间:2024/05/16 19:59
第3章 字符设备驱动程序
本章的目标是写一个完整的字符类设备驱动程序。我们先开发一个字符设备驱动程序仅因为它适合大多数简单的硬件设备。字符设备程序也相对比块设备或网络设备的驱动程序简单一些。当然,我们的最终目标是写一个模块化的字符设备驱动程序,但本章我们暂不讲述模块化的问题。
本章中,所以的代码片段都截取自一个真实的设备驱动程序:这个设备就是scull,是“Simple Character Utility for Loading Localities”的缩写。Scull虽仅操作内存,但是它的确是一个字符设备。这种情况的另一个影响是,只要涉及scull,“设备”这个词就可以同“scull使用的内存区”互换使用。
scull的好处是它与硬件无关,因为每台电脑都有内存,而scull仅仅操作内存,用kmalloc分配内存。任何人都可以编译和运行scull,而且scull可以移植到所有Linux支持的平台上。但另一方面,scull除了演示内核与字符设备驱动程序间的交互过程和让用户运行某些测试程序外,它做不了任何“有用”的事。
scull设计
编写设备驱动程序第一步就是定义驱动程序提供给用户程序的功能(机制)。由于我们的“设备”是电脑内存的一部分,我们可以自由的做我们想做的事情。它可以连续或者随机访问设备;它可以是一个设备,也可以是多个设备,等等。
为了让scull作为一个写或读真实设备的模板时更有用,我们将向你展示如何在电脑的内存之上实现若干设备操作,每一种操作都有自己的特点。
scull的源码实现如下设备。由模块实现的每一种设备都涉及一种类型:
scull0-scull3
4个设备,每个设备都有一块内存空间,都是全局性的和持久性的。全局性是指,如果打开设备多次,所有打开它的文件描述符都共享其中的数据。持久性是指,如果设备关闭后再次打开,数据不丢失。由于可以使用常用命令访问这个设备,如cp,cat以及shell I/O重定向等,这个设备操作非常有趣;本章将深入探讨它的内部结构。
scullpipe0-scullpipe3
4个有点象管道的FIFO(first-in-first-out)设备。一个进程读取另一个进程写入的数据。如果有多个进程读同一个设备,他们就彼此间竞争数据。通过scullpipe的内部结构可以了解阻塞型和非阻塞型读/写在没有中断帮助的情况下是如何实现的。尽管真实的驱动程序利用硬件中断与它们的设备同步,但阻塞型和非阻塞型操作是非常重要的内容,从概念上讲与中断处理(第9章,中断处理,介绍)无关。
scullsingle
scullpriv
sculluid
scullwuid
这些设备驱动与scull0相似,但在何时允许open操作有一些限制。第一个(scullsingle)在同个时间内只允许一个进程使用驱动程序,而scullpriv对每个虚拟控制台(或X terminal
session)是私有的,因为每个控制台/终端都控制台的进程都得到了不同的内存空间。sculluid和scullwuid可以多次打开,但同个时间只能有一个用户能够使用;如果另一个用户锁住了设备,前者返回“Device Busy”的错误,而后者则执行阻塞型open。这些scull的“变异”是在“机制”上加了一些“策略”,这都值得去看的,因为一些设备需要这样的管理。
每一个scull设备都展示了驱动程序不同的特点,而且都不同的难度。本章主要讲解scull0- scull3的内部结构;其他更高级的设备将在第5章中的“一个例子实现:scullpipe”介绍scullpipe和在“设备文件的访问控制”介绍其他设备。
原创粉丝点击