LDD-第一章设备驱动程序简介

设备驱动程序的作用

设备驱动程序在Linux内核中扮演特殊的角色。它们是一个个独立的“黑盒子”,使某个特定的硬件响应一组定义良好的内部编程接口,这些接口完全隐藏了设备工作细节。用户的操作通过一组标准化的调用执行,这些调用独立于特定的驱动程序。驱动的作用是将这些调用映射到作用于实际硬件的设备特有操作上。

 

设备驱动程序在于提供机制,而不是提供策略。大多数编程问题实际上都可以分成两部分:“需要提供什么功能(机制)”和“如何使用这些功能(策略)”。如果这两个问题由程序的不同部分或者不同的程序来处理,这个软件包会更容易开发和根据需要来调整。

内核功能划分

内核功能分为如下几部分:

进程管理:

进程管理负责创建和销毁进程,并处理它们和外部世界之间的连接(输入和输出)。不同进程之间的通信(通过信号、管道或进程间通信原语)是整个系统的基本功能。控制进程如何共享CPU的调度器也是进程管理的一部分。内核进程管理活动就是在单个或多个CPU上实现了多进程的抽象。

内存管理:

内存是计算机的主要资源之一,用来管理内存的策略是决定系统性能的一个关键因素。内核在有限的可用资源之上未每个进程都创建了一个虚拟地址空间。内核的不同部分和内存管理子系统交互时使用一组函数调用,包括简单的malloc/free函数以及其他一些复杂函数。

文件系统:

Unix在很大程度上依赖文件系统的概念,Unix中的每个对象几乎都可以当做文件来看待。内核在没有结构的硬件上构造结构化的文件系统,而文件抽象在整个系统中广泛使用。另外,Linux支持多种文件系统类型,也就是说,在物理介质上组织数据的不同方式。例如,磁盘可以格式化为符合Linux标准的ext3文件系统,也可以格式化为FAT文件系统或其他种类。

设备控制:

几乎每一个系统操作最终都会映射到物理设备上。除了处理器、内存以及其他很有限的几个对象外,所有设备控制操作都由与被控制设备相关的代码完成,这段代码就叫做驱动程序。内核必须为系统中的每个外设嵌入相应的驱动程序。

网络功能:

网络功能也必须有操作系统来管理,因为大部分网络操作和具体进程无关:数据包的传入是异步事件。在某个进程处理这些数据包之前必须手机、标识和分发这些数据包。系统负责在应用程序和网络接口之间传递数据包,并根据网络活动控制程序的执行。另外,所有路由和地址解析问题都由内核处理。

设备和模块分类

Linux有一个很好的特性:内核提供的特性可以在运行时进行扩展。也就是说,当系统启动运行时,可以向内核增加(insmod)或者删除功能(rmmod)。

Linux系统将设备分成三个基本类型:字符设备、块设备、网络设备。

字符设备:

字符(char)设备是能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动至少要实习open、close、read、write系统调用。字符终端(/dev/console)和串口(/dev/ttys0)就是两个字符设备。字符设备可以通过文件系统节点来访问,如/dev/tty1。这些设备文件和普通文件之间的唯一差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道。当然,也存在具有数据区特性的字符设备,访问他们时,可以前后移动访问位置,如帧抓取器,应用程序可以用mmap或lseek访问抓取的整个图像。

块设备

和字符设备类似,块设备也是通过/dev目录下的文件系统节点进行访问。块设备(如磁盘)上能够容纳文件系统。在大多数Unix系统中,进行I/O操作时,块设备每次只能传输一个或多个完整的块,每个块包含512字节(或2的更高次幂字节的数据)。Linux可以让应用程序像字符设备一样读写块设备,允许一次传递任意多字节的数据。因而,块设备和字符设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口。而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口。

网络接口

任何网络事务都经过一个网络接口形成,即一个能够和其他主机交换数据的设备。通常,接口是硬件设备,也有可能是纯软件设备,如回环(loopback)接口。网络接口由内核中的网络子系统驱动,负责发送和接收数据包,但它不需要了解每项事务如何映射到实际传送的数据包。许多网络连接(尤其是使用TCP协议的连接)是面向流的,但网络设备却围绕数据包的传输和接收设计,网络驱动程序不需要知道各个连接的相关信息,它只要处理数据包即可。由于不是面向流的设备,因此将网络设备映射到文件系统中的节点(比如/dev/tty1)比较困难。Unix访问网络接口的方法仍然是给它们分配一个唯一的名字(比如eth0),但这个名字在文件系统中不存在对应的节点。内核和网络设备驱动程序间的通信,不同于内核和字符设备及块设备之间的通信,内核调用一套和数据包传输相关的函数而不是read、write等。

猜你喜欢

转载自blog.csdn.net/weixin_42343585/article/details/81149401