LINUX PCI 设备驱动程序编写详解
LINUX
PCI 设备驱动程序
编写详解1
1 注:本文针对linux-2.4 内核版本。
1/25 July 2007
LINUX PCI 设备驱动程序编写详解
中国科学技术大学
(安徽,合肥)
近代物理系
快电子实验室
曹桂平
2/25 July 2007
LINUX PCI 设备驱动程序编写详解
This page is intentionally left blank.
3/25 July 2007
LINUX PCI 设备驱动程序编写详解
引言
底层驱动程序是作为用户程序与底层硬件之间的中介存在的,这是一般的说法。其实二者之
间还有一个虚拟文件系统作为用户程序和驱动程序之间的桥梁。虚拟文件系统所隐含的思想
是把表示很多不同种类文件系统的广泛信息放入内核,其中有一个字段或函数来支持 Linux
支持的任何文件系统所提供的任何操作。对所调用的每个读写或其它函数,内核都把它们替
换成支持本地 Linux 文件系统,NT 文件系统,或者文件所在的任何其它文件系统的实际函
数。类 Unix 操作系统都是基于文件概念的,文件是以字符序列构成的信息载体,根据这一
点,可以把 I/O 设备(如各种 PCI 接口芯片)也作为一种文件形式看待,即设备文件。与磁
盘上的普通文件进行交互所用的同一系统调用可直接用于 I/O 设备。根据设备驱动程序的基
本特性,设备文件可以分为两种:块和字符。二者差异如下:
1.块设备的数据可以被随机访问,而且从用户的观点看,传送任何数据块所需的时间都是
较少且大致相同的。块设备的典型例子就是磁盘,软盘,CD-ROM 及 DVD 播放器。
2 .字符设备的数据或者不可随机访问,或者可以随机访问但访问所需时间很大程度上依赖
于数据在设备内的位置。这样的例子有声卡,大多数 PCI 设备。
本文主要针对 PCI 设备,着重论述字符设备驱动程序。较之其它这方面的文章,本文不仅
仅介绍 Linux 设备驱动程序编写中所涉及的内核辅助函数,并且结合 Linux 内核源码分析这
些辅助函数的实现,以及各个函数之间的关系,从而使得读者对内部机理有一个清楚的了解,
继而对于 Linux 下设备驱动程序的编写做到底气十足。
Linux 系统下 PCI 设备的驱动程序编写涉及到 Linux 的各个主要方面,从编程角度看,主要
包括驱动程序函数集注册,中断注册,DMA 操作处理,代码同步,模块动态加载。本文结
合内核源码着重从这几个方面全面阐述设备驱动程序的编写。文章组织如下:第一节介绍驱
动程序注册;第二节讨论 DMA 传输机制;第三节介绍中断注册;第四节简单阐述代码同步
问题;第五节着重介绍了驱动程序的动态加载。源码分析使用linux-2.4.20 内核版本。
4/25 July 2007
LINUX PCI 设备驱动程序编写详解
第一节 驱动程序的注册
Linux 为每个文件都会分配一个设备号。这是一个 16 位的数据类型。高 8 位称为主设备号,
这是内核用来将文件与其驱动程序联系起来的桥梁。主设备号是从 1 到 254 之间标志设备类
型的一个数。通常有相同主设备号的所有设备都共享相同的文件操作集合,它们由同一设备
驱动程序来处理。次设备号用低 8 位表示,用于驱动程序内部,内