1 驱动程序的角色
驱动程序需要实现“机制”,而不是实现“策略”。
- 机制:提供了什么能力
- 策略:如何使用这些能力
2 内核划分
-
进程管理:创建和销毁进程,处理进程与外部世界的连接(输入和输出)、进程间通信、进程调度等。
-
内存管理:内存是系统的主要资源之一,内存管理策略对于系统性能至关重要。
-
文件系统:内核在非结构化的硬件上实现了结构化的文件系统。Unix中几乎任何东西都可以作为文件进行处理。
-
设备控制:几乎每个系统操作最终都映射到一个物理设备上。除了处理器、内存和少量其他实体外,所有设备控制操作都是由特定于设备的代码实现的,这些代码就是设备驱动程序。内核必须为系统中存在的每个外设嵌入设备驱动程序。设备控制是本书主要关注的内核功能。
-
网络:网络必须由操作系统管理,因为报文分组是异步到达的,大多数网络操作都不是特定于一个进程的。系统需要处理数据分组在程序和网络接口间的传递问题,必须根据网络情况控制程序的执行(流量控制)。此外,路由和地址解析也由内核实现。
3 可装载模块
4 设备和模块分类
三种类型的设备和驱动模块:
-
字符设备
字符设备是可以作为字节流进行访问的设备,实现对设备的字节流方式访问是字符设备驱动的任务。字符设备驱动至少需要实现open、close、read 和 write 系统调用。文本控制台(/dev/console)和串口(/dev/ttyS0等)是字符设备的实例,因为它们完美地被流抽象表示。字符设备可以通过文件系统节点,如/dev/tty1和/dev/lp0,进行访问。字符设备和普通文件的唯一不同只是,总是可以在普通文件中来回移动,但字符设备仅仅是数据通道,只能顺序访问。然而,也存在可以看做数据区域、可以在其中来回移动的字符设备。例如,帧捕捉器通常实现了这种能力,使得应用程序可以使用mmap或者lseek访问已经获取的整个图像。
-
块设备
跟字符设备一样,块设备也是通过/dev目录中的文件系统节点进行访问的。块设备是可以在其上驻留文件系统的设备,比如说,磁盘。在很多Unix系统中,块设备只能处理传输一个或者多个完整块的I/O操作。块长度通常为512字节。Linux却允许像字符设备那样读写块设备,即允许一次传输任意字节数。这样,块设备和字符设备的唯一差别仅仅是内核管理其数据的方式不同,以及由此带来的内核/驱动软件接口的差异。和字符设备一样,每个块设备都可以通过文件系统节点进行访问,它们之间的不同对用户是透明的。然而,块设备到内核的接口是完全不同于字符设备的。
-
网络接口
任何网络传输都是通过网络接口进行的。网络接口是可以与其他主机交换数据的设备。通常网络接口是一个硬件设备,然而也可以是像环回接口这样的纯软件设备。网络接口由内核的网络子系统驱动,负责收发数据分组,但网络接口不知道单次传输是如何映射到被传输的分组的。很多网络连接(特别是使用TCP的)通常是面向流的,但网络设备通常是围绕收发分组进行设计的。网络驱动只处理分组,不知道网络连接的存在。
因为不是面向流的设备,所以网络接口不能像/dev/tty1那样容易地映射到文件系统中的某个节点。Unix提供的对网络接口的访问方法仍然是为其分配唯一的名字(如eth0),但是分配的名字不对应文件系统中的实体。内核和网络设备驱动间的通信方式是完全不同于字符和块设备驱动的:不使用read和write,而是调用与分组传输相关的函数。
也存在不同于上面论述的设备类型分类的其他的设备驱动分类方式。通常,一些与额外的内核层次一起工作的驱动程序会支持某种类型设备的功能。比如说,USB模块、串口模块、SCSI模块等等。每个USB设备由与USB子系统一同工作的一个USB模块驱动,但是设备本身在系统中表现为一个字符设备(如USB串口)、块设备(如USB读卡器)或者网络设备(如USB以太网接口)。
近年来内核中加入了其他类型的设备驱动,如火线驱动和I2O驱动。与处理USB和SCSI驱动的方式一样,内核开发者收集了这类设备的特征,提供给驱动开发者,以避免重复的工作和引入问题,因而简化和加强了编写这类驱动的过程。
除了设备驱动外,内核中其他一些硬件和软件功能也被模块化,最常见的例子就是文件系统。文件系统决定如何在块设备上组织信息来代表目录和文件树。这种实体不是设备驱动,因为没有哪个设备与信息的组织方式相关。文件系统是一种软件驱动,因为它把底层数据结构映射到高层数据结构。文件系统决定文件名可以是多长的,以及在目录中存储每个文件的哪些信息。文件系统模块必须通过映射文件名和路径(以及其他信息,如访问模式)到存储在数据块中的数据结构的方式,来实现访问目录和文件的最底层系统调用。这种接口完全与磁盘(或者其他媒体)数据传输无关,数据传输是由块设备驱动完成的。
解码文件系统信息的能力位于内核的最底层,这种能力是极其重要的。为新的CD-ROM编写的块设备驱动,如果不能在其容纳的数据上运行ls或者cp命令,那么是无用的。Linux支持文件系统模块的概念。文件系统模块的软件接口声明了可以在文件系统节点、目录、文件和超级块上执行的不同操作。程序员很少需要编写文件系统模块,因为官方的内核已经包含大多数重要文件系统类型的代码。
5
6