Linux设备驱动编程-字符设备文件
Linux设备驱动编程-字符设备文件
PAGE
PAGE 3/ NUMPAGES 33
IA Division2007-9-7
IA Division
2007-9-7
Linux设备驱动编程-字符设备文件
Version 1.0
Revision History
Version
Date
Originator
Description
1.0
2007-9-11
阎东
目录
TOC \o "1-3" \h \z \u Version 1.0 1
Revision History 2
1前言 4
2scull的设计 4
3主次编号 4
3.1设备编号的内部表示 5
3.2分配和释放设备编号 6
3.3主编号的动态分配 7
4一些重要数据结构 13
4.1文件操作 13
4.2文件结构 16
4.3inode 结构 18
5字符设备注册 18
5.1scull 中的设备注册 19
5.2老方法 20
6open 和 release 21
6.1open 方法 21
6.2release 方法 22
7scull 的内存使用 23
8读和写 25
8.1read 方法 28
8.2write 方法 29
8.3readv 和 writev 31
9测试 32
9.1编辑测试文件 32
9.2测试 32
前言
本文的目的是编写一个完整的字符设备驱动.开发一个字符驱动是因为这一类适合大部分简单硬件设备.
贯串本文, 将展示从一个真实设备驱动提取的代码片段: scull( Simple Character Utility for Loading Localities). scull 是一个字符驱动, 操作一块内存区域好像它是一个设备. 在本文, 因为 scull 的这个怪特性,可互换地使用设备这个词和"scull使用的内存区".
scull 的优势在于它不依赖硬件. scull 只是操作一些从内核分配的内存. 任何人都可以编译和运行scull, 并且 scull 在 Linux 运行的体系结构中可移植. 另一方面, 这个设备除了演示内核和字符驱动的接口和允许用户运行一些测试之外, 不做任何有用的事情.
scull的设计
编写驱动的第一步是定义驱动将要提供给用户程序的能力(机制).因为我们的"设备"是计算机内存的一部分, 我们可自由做我们想做的事情. 它可以是一个顺序的或者随机存取的设备, 一个或多个设备, 等等.
为使 scull 作为一个模板来编写真实设备的真实驱动, 我们将展示给你如何在计算机内存上实现几个设备抽象, 每个有不同的个性.scull 源码实现下面的设备.
模块实现的每种设备都被引用做一种类型.
scull0 到 scull3
4 个设备, 每个由一个全局永久的内存区组成. 全局意味着如果设备被多次打开, 设备中含有的数据由所有打开它的文件描述符共享. 永久意味着如果设备关闭又重新打开, 数据不会丢失. 这个设备用起来有意思, 因为它可以用惯常的命令来存取和测试, 例如 cp,cat, 以及 I/O 重定向.
主次编号
字符设备通过文件系统中的名子来存取. 那些名子称为文件系统的特殊文件, 或者设备文件, 或者文件系统的简单结点; 惯例上它们位于 /dev 目录. 字符驱动的特殊文件由使用 ls -l 的输出的第一列的"c"标识. 块设备也出现在 /dev 中, 但是它们由"b"标识. 本章集中在字符设备, 但是下面的很多信息也适用于块设备.
如果你发出 ls -l 命令, 你会看到在设备文件项中有 2 个数(由一个逗号分隔)在最后修改日期前面,这里通常是文件长度出现的地方. 这些数字是给特殊设备的主次设备编号. 下面的列表显示了一个典型系统上出现的几个设备. 它们的主编号是 1, 4, 7, 和 10, 而次编号是 1, 3, 5, 64, 65, 和 129.
crw-rw-rw- 1 root root 1, 3 Apr 11 2002 null
crw 1 root root 10, 1 Apr 11 2002 psaux
crw 1 root root 4, 1 Oct 28 03:04 tty1
crw-rw-rw- 1 root tty 4, 64 Apr 11 2002 ttys0
crw-rw 1 root uucp 4, 65 Apr 11 2002 ttyS1
crw--w 1 vcsa tty 7, 1 Apr 11 2002 vcs1
crw