Linux设备驱动程序(一)——设备驱动简介

2023-08-10 10:35:32 浏览数 (1)

前言

这一部分主要是用来介绍 Linux 设备驱动程序的一些基本概念,包括:Linux 设备驱动程序的作用、内核功能的划分、设备和模块的分类以及版本编号。

一、Linux 设备驱动程序的作用

设备驱动程序就像一个个的“黑盒子”,使某个特定硬件响应一个定义良好的内部编程接口,这些操作完全隐藏了设备的工作细节。用户的操作通过一组标准化的调用执行,而这些调用独立于特定的驱动程序。将这些调用映射到作用于实际硬件的设备特有操作上,则是设备驱动程序的任务。

简洁的来说设备驱动程序的作用在于提供机制(需要提供什么功能),而不在于提供策略(这些功能怎么使用)。 拓展:

编写驱动程序应该注意这个基本概念:编写内核代码来存取硬件, 但是不能强加特别的策略给用户, 因为不同>的用户有不同的需求. 驱动程序应当做到使硬件可用, 将所有关于如何使用硬件的事情留给应用程序。

驱动程序设计要考虑的三个方面:

  • 提供给用户尽可能多的选项
  • 编写驱动程序要占用的时间
  • 尽量保持程序简单避免产生过多的错误

二、内核功能的划分

内核功能可以主要划分为以下五个部分:

  • 进程管理 内核负责创建和销毁进程,并处理它们与外部世界的联系(输入和输出)。不同进程间通讯(通过信号, 管道, 或者进程间通讯原语)对整个系统功能来说是基本的,也由内核处理。另外,调度器,控制进程如何共享 CPU,是进程管理的一部分。更通常地,内核的进程管理活动实现了多个进程在一个单个或者几个 CPU 之上的抽象。
  • 内存管理 计算机的内存是主要的资源,处理它所用的策略对系统性能是至关重要的。内核为所有进程的每一个都在有限的可用资源上建立了一个虚拟地址空间。内核的不同部分与内存管理子系统通过一套函数调用交互,从简单 malloc/free 对到更多更复杂的功能。
  • 文件系统 Unix 在很大程度上基于文件系统的概念;几乎 Unix 中的任何东西都可看作一个文件。内核在非结构化的硬件之上建立了一个结构化的文件系统,结果是文件的抽象非常多地在整个系统中应用。另外,Linux 支持多个文件系统类型,就是说,物理介质上不同的数据组织方式。例如,磁盘可被格式化成标准 Linux 的 ext3 文件系统,普遍使用的 FAT 文件系统,或者其他几个文件系统。
  • 设备控制 几乎每个系统操作最终都映射到一个物理设备上。除了处理器,内存和非常少的别的实体之外,全部中的任何设备控制操作都由特定于要寻址的设备相关的代码来进行。这些代码称为设备驱动,内核中必须嵌入系统中出现的每个外设的驱动,从硬盘驱动到键盘和磁带驱动器。
  • 网络 网络必须由操作系统来管理,因为大部分网络操作不是特定于某一个进程:进入系统的报文是异步事件。报文在某一个进程接手之前必须被收集,识别,分发。系统负责在程序和网络接口之间递送数据报文,它必须根据程序的网络活动来控制程序的执行。另外,所有的路由和地址解析问题都在内核中实现。

三、设备和模块的分类

以 Linux 的方式看待设备可区分为 3 种基本设备类型,每个模块常常实现 3 种类型中的 1 种,因此可分类成字符模块,块模块,或者一个网络模块。

3 类驱动如下:

  • 字符设备 一个字符(char)设备是一种可以当作一个字节流来存取的设备(如同一个文件); 一个字符驱动负责实现这种行为,这样的驱动常常至少实现 open,close,read,和 write 系统调用。文本控制台(/dev/console)和串口(/dev/ttyS0 )是字符设备的例子,因为它们很好地展现了流的抽象。字符设备通过文件系统结点来存取,例如 /dev/tty1 和 /dev/lp0。在一个字符设备和一个普通文件之间唯一有关的不同就是,你经常可以在普通文件中移来移去,但是大部分字符设备仅仅是数据通道,你只能顺序存取。然而,存在看起来象数据区的字符设备,你可以在里面移来移去。例如,frame grabber 经常这样,应用程序可以使用 mmap 或者 lseek 存取整个要求的图像。
  • 块设备 如同字符设备,块设备通过位于 /dev 目录的文件系统结点来存取。一个块设备(例如一个磁盘)应该是可以驻有一个文件系统的。在大部分的 Unix 系统,一个块设备只能处理这样的 I/O 操作,传送一个或多个长度经常是 512 字节(或一个更大的 2 的幂的数)的整块。Linux,相反,允许应用程序读写一个块设备象一个字符设备一样 – 它允许一次传送任意数目的字节。结果就是,块和字符设备的区别仅仅在内核在内部管理数据的方式上,并且因此在内核/驱动的软件接口上不同。如同一个字符设备,每个块设备都通过一个文件系统结点被存取的,它们之间的区别对用户是透明的。块驱动和字符驱动相比,与内核的接口完全不同。
  • 网络接口 任何网络事务都通过一个接口来进行,就是说,一个能够与其他主机交换数据的设备。通常,一个接口是一个硬件设备,但是它也可能是一个纯粹的软件设备,比如环回接口。一个网络接口负责发送和接收数据报文,在内核网络子系统的驱动下,不必知道单个事务是如何映射到实际的被发送的报文上的。很多网络连接(特别那些使用 TCP 的)是面向流的,但是网络设备却常常设计成处理报文的发送和接收。一个网络驱动对单个连接一无所知;它只处理报文。 既然不是一个面向流的设备,一个网络接口就不象 /dev/tty1 那么容易映射到文件系统的一个结点上。Unix 提供的对接口的存取的方式仍然是通过分配一个名子给它们(例如 eth0), 但是这个名子在文件系统中没有对应的入口。 内核与网络设备驱动间的通讯与字符和块设备驱动所用的完全不同。不用 read 和 write,内核调用和报文传递相关的函数。

有其他的划分驱动模块的方式,与上面的设备类型是正交的。通常,某些类型的驱动与给定类型设备的其他层的内核支持函数一起工作。例如,你可以说 USB 模块,串口模块,SCSI 模块,等等。每个 USB 设备由一个 USB 模块驱动,与 USB 子系统一起工作,但是设备自身在系统中表现为一个字符设备(比如一个 USB 串口),一个块设备(一个 USB内存读卡器), 或者一个网络设备(一个 USB 以太网接口)。

四、版本编号

至于说内核,偶数的内核版本(就是说,2.6.x)是稳定的,用来做通用的发布。奇数版本(例如 2.7.x), 相反,是开发快照并且是非常短暂的;它们的最新版本代表了开发的当前状态,但是会在几天内就过时了。

0 人点赞