Linux设备文件简介

Linux设备文件简介
Linux设备文件简介

Linux设备文件简介

版权声明

本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发,但必须保留作者署名,亦不得对声明中的任何条款作任何形式的修改,也不得附加任何其它条件。您可以自由链接、下载、传播此文档,但前提是必须保证全文完整转载,包括完整的版权信息和作译者声明。

其他作品

本文作者十分愿意与他人共享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有作品的列表:

金步国作品列表

BUG报告,切磋与探讨

由于作者水平有限,因此不能保证作品内容准确无误,请在阅读中自行鉴别。如果你发现了作品中的错误,请您来信指出,哪怕是错别字也好,任何提高作品质量的建议我都将虚心接纳。如果你愿意就作品中的相关内容与我进行进一步切磋与探讨,也欢迎你与我联系。联系方式:MSN: csfrank122@https://www.360docs.net/doc/cd4570106.html,

概述

设备管理是linux中比较基础的东西,但是由于Linux智能程度的越来越高,Udev 的使用越来越广泛,使得越来越多的Linux新用户对 /dev 目录下的东西变得不再熟悉。有时候遇见问题就会变得抓狂。

Linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取)、块设备(有缓冲且可以随机存取)。每个字符设备和块设备都必须有主、次设备号,主设备号相同的设备是同类设备(使用同一个驱动程序)。这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的

物理硬件,又称为"虚拟设备")。每个设备在 /dev 目录下都有一个对应的文件(节点)。可以通过 cat /proc/devices 命令查看当前已经加载的设备驱动程序的主设备号。内核能够识别的所有设备都记录在原码树下的

Documentation/devices.txt 文件中。在 /dev 目录下除了字符设备和块设备节点之外还通常还会存在:FIFO管道、Socket、软/硬连接、目录。这些东西没有主/次设备号。

设备文件

Linux内核所能识别的所有设备都记录在

https://www.360docs.net/doc/cd4570106.html,/docs/device-list/

而内核原码树中的 Documentation/devices.txt 可能不是最新版本。

了解这些设备的最基本要求就是对每个设备文件的含义了如指掌,下面列出常见的设备文件以及相应的含义(比较偏僻的就省略了)。

----------------------------------------------------------------------

主设备号设备类型

次设备号=文件名简要说明

----------------------------------------------------------------------

0 未命名设备(例如:挂载的非设备)

0 = 为空设备号保留

1 char 内存设备

1 = /dev/mem 直接存取物理内存

2 = /dev/kmem 存取经过内核虚拟之后的内存

3 = /dev/null 空设备。任何写入都将被直接丢弃,任何读取都将得到EOF。

4 = /dev/port 存取I/O 端口

5 = /dev/zero 零字节源,只能读取到无限多的零字节。

7 = /dev/full 满设备。任何写入都将失败,并把errno设为ENOSPC以表示没有剩余空间。

8 = /dev/random 随机数发生器。完全由用户的输入来产生随机数。

如果用户停止所有动作,则停止产生新的随机数。

9 = /dev/urandom 更快,但是不够安全的随机数发生器。尽可能由用户的输入来产生随机数,

如果用户停止所有动作,则把已经产生的随机数做为种子来产生新的随机数。

10 = /dev/aio 异步I/O 通知接口

11 = /dev/kmsg 任何对该文件的写入都将作为printk 的输出

1 block RAM disk

0 = /dev/ram0 第1个RAM disk (initrd 只能使用ram0)

1 = /dev/ram1 第2个RAM disk

...

200 = /dev/ram200 第200个RAM disk

4 char TTY(终端)设备

0 = /dev/tty0 当前虚拟控制台

1 = /dev/tty1 第1个虚拟控制台

...

63 = /dev/tty63 第63个虚拟控制台

4 block 如果根文件系统以是以只读方式挂载的,那么就不可能创建真正的设备节点,

此时就使用该设备作为动态分配的主(major)设备的别名

0 = /dev/root

5 char 其他TTY 设备

0 = /dev/tty 当前TTY 设备

1 = /dev/console 系统控制台(一般是/dev/tty0)

2 = /dev/ptmx 所有PTY master 的复用器

7 char 虚拟控制台捕捉设备(这些设备既允许读也允许写)

0 = /dev/vcs 当前虚拟控制台(vc)的文本内容

1 = /dev/vcs1 tty1 的文本内容

...

63 = /dev/vcs63 tty63 的文本内容

128 = /dev/vcsa 当前虚拟控制台(vc)的文本/属性内容

129 = /dev/vcsa1 tty1 的文本/属性内容

...

191 = /dev/vcsa63 tty63 的文本/属性内容

7 block 回环设备(用一个普通的磁盘文件来模拟一个块设备)

对回环设备的绑定由mount(8) 或losetup(8) 处理

0 = /dev/loop0 第1个回环设备

1 = /dev/loop1 第2个回环设备

...

8 block SCSI 磁盘(0-15)

0 = /dev/sda 第1个SCSI 磁盘(整个磁盘)

16 = /dev/sdb 第2个SCSI 磁盘(整个磁盘)

32 = /dev/sdc 第3个SCSI 磁盘(整个磁盘)

...

240 = /dev/sdp 第16个SCSI 磁盘(整个磁盘)

分区表示方法如下(以第3个SCSI 磁盘为例)

33 = /dev/sdc1 第1个分区

34 = /dev/sdc2 第2个分区

...

47 = /dev/sdc15 第15个分区

对于Linux/i386来说,分区1-4是主分区,5-15是逻辑分区。

9 block Metadisk(RAID)设备

0 = /dev/md0 第1组metadisk

1 = /dev/md1 第2组metadisk

...

metadisk 驱动用于将同一个文件系统分割到多个物理磁盘上。

10 char 非串口鼠标,各种杂项设备和特性

1 = /dev/psaux PS/2鼠标

131 = /dev/temperature 机器内部温度

134 = /dev/apm_bios APM(高级电源管理) BIOS

135 = /dev/rtc 实时时钟(Real Time Clock)

144 = /dev/nvram 非易失配置RAM

162 = /dev/smbus 系统管理总线(System Management Bus)

164 = /dev/ipmo Intel的智能平台管理(Intelligent Platform Management)接口

173 = /dev/ipmikcs 智能平台管理(Intelligent Platform Management)接口

175 = /dev/agpgart AGP图形地址重映射表(Graphics Address Remapping Table)

182 = /dev/perfctr 性能监视计数器

183 = /dev/hwrng 通用硬件随机数发生器

184 = /dev/cpu/microcode CPU微代码更新接口

186 = /dev/atomicps 进程状态数据的原子快照

188 = /dev/smbusbios S MBus(系统管理总线) BIOS

200 = /dev/net/tun TAP/TUN 网络设备(TAP/TUN以软件的方式实现了网络设备)

TAP模拟了以太网帧(第二层),TUN模拟了IP包(第三层)。

202 = /dev/emd/ctl 增强型Metadisk RAID (EMD) 控制器

220 = /dev/mptctl Message passing technology (MPT) control

223 = /dev/input/uinput 用户层输入设备驱动支持

227 = /dev/mcelog X86_64 Machine Check Exception driver

228 = /dev/hpet HPET driver

229 = /dev/fuse Fuse(用户空间的虚拟文件系统)

231 = /dev/snapshot 系统内存快照

232 = /dev/kvm 基于内核的虚构机(基于AMD SVM和Intel VT硬件虚拟技术)

11 block SCSI CD-ROM 设备

0 = /dev/scd0 第1个SCSI CD-ROM

1 = /dev/scd1 第2个SCSI CD-ROM

...

13 char 核心输入设备

32 = /dev/input/mouse0 第1个鼠标

33 = /dev/input/mouse1 第2个鼠标

...

62 = /dev/input/mouse30 第31个鼠标

63 = /dev/input/mice 所有鼠标的统一

64 = /dev/input/event0 第1个事件队列

65 = /dev/input/event1 第2个事件队列

...

95 = /dev/input/event1 第32个事件队列21 char 通用SCSI 设备(通常是SCSI光驱)

0 = /dev/sg0 第1个通用SCSI 设备

1 = /dev/sg1 第2个通用SCSI 设备

...

29 char 通用帧缓冲(frame buffer)设备

0 = /dev/fb0 第1个帧缓冲设备

1 = /dev/fb1 第2个帧缓冲设备

...

31 = /dev/fb31 第32个帧缓冲设备

30 char iBCS-2 兼容设备

0 = /dev/socksys 套接字访问接口

1 = /dev/spx SVR3 本地X 接口

32 = /dev/inet/ip 网络访问接口

33 = /dev/inet/icmp

34 = /dev/inet/ggp

35 = /dev/inet/ipip

36 = /dev/inet/tcp

37 = /dev/inet/egp

38 = /dev/inet/pup

39 = /dev/inet/udp

40 = /dev/inet/idp

41 = /dev/inet/rawip

此外,iBCS-2 还需要下面的连接必须存在

/dev/ip -> /dev/inet/ip

/dev/icmp -> /dev/inet/icmp

/dev/ggp -> /dev/inet/ggp

/dev/ipip -> /dev/inet/ipip

/dev/tcp -> /dev/inet/tcp

/dev/egp -> /dev/inet/egp

/dev/pup -> /dev/inet/pup

/dev/udp -> /dev/inet/udp

/dev/idp -> /dev/inet/idp

/dev/rawip -> /dev/inet/rawip

/dev/inet/arp -> /dev/inet/udp

/dev/inet/rip -> /dev/inet/udp

/dev/nfsd -> /dev/socksys

/dev/X0R -> /dev/null

36 char Netlink 支持

0 = /dev/route 路由, 设备更新, kernel to user

3 = /dev/fwmonitor Firewall packet 复制

59 char sf 防火墙模块

0 = /dev/firewall 与sf 内核模块通信

65 block SCSI 磁盘(16-31)

0 = /dev/sdq 第17个SCSI 磁盘(整个磁盘)

16 = /dev/sdr 第18个SCSI 磁盘(整个磁盘)

32 = /dev/sds 第19个SCSI 磁盘(整个磁盘)

...

240 = /dev/sdaf 第32个SCSI 磁盘(整个磁盘)

66 block SCSI 磁盘(32-47)

0 = /dev/sdag 第33个SCSI 磁盘(整个磁盘)

16 = /dev/sdah 第34个SCSI 磁盘(整个磁盘)

32 = /dev/sdai 第35个SCSI 磁盘(整个磁盘)

...

240 = /dev/sdav 第48个SCSI 磁盘(整个磁盘)

89 char I2C 总线接口

0 = /dev/i2c-0 第1个I2C 适配器

1 = /dev/i2c-1 第2个I2C 适配器

...

98 block 用户模式下的虚拟块设备(分区处理方式与SCSI 磁盘相同)

0 = /dev/ubda 第1个用户模式块设备

16 = /dev/udbb 第2个用户模式块设备

...

103 block 审计(Audit)设备

0 = /dev/audit 审计(Audit)设备

128-135 char Unix98 PTY master

这些设备不应当存在设备节点,而应当通过/dev/ptmx 接口访问。

136-143 char Unix98 PTY slave

这些设备节点是自动生成的(伴有适当的权限和模式),不能手动创建。

方法是通过使用适当的mount 选项(通常是:

mode=0620,gid=<"tty"组的gid>)

将devpts 文件系统挂载到/dev/pts 目录即可。

0 = /dev/pts/0 第1个Unix98 PTY slave

1 = /dev/pts/1 第2个Unix98 PTY slave

...

153 block Enhanced Metadisk RAID (EMD) 存储单元(分区处理方式与SCSI 磁盘相同)

0 = /dev/emd/0 第1个存储单元

1 = /dev/emd/0p1 第1个存储单元的第1个分区

2 = /dev/emd/0p2 第1个存储单元的第2个分区

...

15 = /dev/emd/0p15 第1个存储单元的第15个分区

16 = /dev/emd/1 第2个存储单元

32 = /dev/emd/2 第3个存储单元

...

240 = /dev/emd/15 第16个存储单元

180 char USB 字符设备

96 = /dev/usb/hiddev0 第1个USB人机界面设备(鼠标/键盘/游戏杆/手写版等人操作计算机的设备)

...

111 = /dev/usb/hiddev15 第16个USB人机界面设备

180 block USB 块设备(U盘之类)

0 = /dev/uba 第1个USB 块设备

8 = /dev/ubb 第2个USB 块设备

16 = /dev/ubc 第3个USB 块设备

...

192 char 内核profiling 接口

0 = /dev/profile Profiling 控制设备

1 = /dev/profile0 CPU 0 的Profiling 设备

2 = /dev/profile1 CPU 1 的Profiling 设备

...

193 char 内核事件跟踪接口

0 = /dev/trace 跟踪控制设备

1 = /dev/trace0 CPU 0 的跟踪设备

2 = /dev/trace1 CPU 1 的跟踪设备

...

195 char Nvidia 图形设备(比如显卡)

0 = /dev/nvidia0 第1个Nvidia 卡

1 = /dev/nvidia1 第2个Nvidia 卡

...

255 = /dev/nvidiactl Nvidia 卡控制设备

202 char 特定于CPU模式的寄存器(model-specific register,MSR)

0 = /dev/cpu/0/msr CPU 0 的MSRs

1 = /dev/cpu/1/msr CPU 1 的MSRs

...

203 char CPU CPUID 信息

0 = /dev/cpu/0/cpuid CPU 0 的CPUID

1 = /dev/cpu/1/cpuid CPU 1 的CPUID

...

有没有感到很奇怪?为什么没有 /dev/hda 这样的设备,难道不常用么?原因在于从 2.6.19 版本开始,内核引入了新的ATA驱动,将SATA/PATA硬盘统一使用/dev/sd? 来表示了,所以 /dev/hd? 就没有存在的必要了。具体说来也就是你在编译内核的时候不要再使用"ATA/ATAPI/MFM/RLL support"下面的驱动,而是使用更新的"Serial ATA and Parallel ATA drivers"驱动。

链接、套接字、管道、挂载点

这部分详细说明一些应该或可能存在于 /dev 目录之外的文件。链接最好使用与这里完全相同的格式(绝对路径或相对路径)。究竟是使用硬链接(hard)还是软连接(symbolic)取决于不同的设备。

必须的链接

必须在所有的系统上都存在这些连接:

链接目标链接类型简要说明

/dev/fd /proc/self/fd symbolic 文件描述府

/dev/stdin fd/0 symbolic 标准输入文件描述府

/dev/stdout fd/1 symbolic 标准输出文件描述符

/dev/stderr fd/2 symbolic 标准错误文件描述符

/dev/nfsd socksys symbolic 仅为iBCS-2 所必须

/dev/X0R null symbolic 仅为iBCS-2 所必须[注意] /dev/X0R 是<字母X>-<数字0>-<字母R>

推荐的链接

推荐在所有的系统上都存在这些连接:

链接目标链接类型简要说明

/dev/core /proc/kcore symbolic 为了向后兼容

/dev/ramdisk ram0 symbolic 为了向后兼容

/dev/ftape qft0 symbolic 为了向后兼容

/dev/bttv0 video0 symbolic 为了向后兼容

/dev/radio radio0 symbolic 为了向后兼容

/dev/i2o* /dev/i2o/* symbolic 为了向后兼容

/dev/scd? sr? hard 代替SCSI CD-ROM 的名字

本地定义的链接

下面的链接很可能需要根据机器的实际硬件配置创建其中的一部分甚至全部。这些链接仅仅是为了迎合习惯用法,它们既非必须也非推荐。

链接目标链接类型简要说明

/dev/mouse mouse port symbolic 当前鼠标

/dev/tape tape device symbolic 当前磁带

/dev/cdrom CD-ROM device symbolic 当前CD-ROM /dev/cdwriter CD-writer symbolic 当前CD-writer

/dev/scanner scanner symbolic 当前扫描仪

/dev/modem modem port symbolic 当前调制解调器

/dev/root root device symbolic 当前根文件系统所在设备/dev/swap swap device symbolic 当前swap所在设备

/dev/modem 不应当用于能够同时支持呼入和呼出的modem,因为往往会导致锁文件问题。如果存在 /dev/modem ,那么它应当指向一个恰当的主 TTY 设备。

对于SCSI设备,/dev/tape 和 /dev/cdrom 应该分别指向"cooked"设备

/dev/st* 和 /dev/sr* ;而 /dev/cdwriter 和 /dev/scanner 应当分别指向恰当的 /dev/sg* 。

/dev/mouse 可以指向一个主串行 TTY 设备、一个硬件鼠标、或者一个对应鼠标驱动程序的套接字(例如 /dev/gpmdata)。

套接字和管道

持久套接字和命名管道可以存在于 /dev 中。常见的有:

/dev/printer socket lpd 本地套接字

/dev/log socket syslog 本地套接字

/dev/gpmdata socket gpm 鼠标多路复用器(multiplexer)

/dev/gpmctl socket (LFS-LiveCD中出现)

/dev/initctl fifo pipe init 监听它并从中获取信息(用户与init 进程交互的通道)

挂载点

以下名称被保留用于挂载特殊的文件系统。这些特殊的文件系统只提供内核界面而不提供标准的设备节点。

/dev/pts devpts PTY slave 文件系统

/dev/shm tmpfs 提供对POSIX 共享内存的直接访问

终端设备

终端(或TTY)设备是一种特殊的字符设备。终端设备是可以在会话中扮演控制终端角色的任何设备,包括:虚拟控制台、串行接口(已废弃)、伪终端(PTY)。

所有的终端设备共享一个通用的功能集合:line discipline,它既包含通用的终端 line discipline 也包含SLIP和PPP模式。所有的终端设备的命名都很相似。这部分内容将解释命名规则和各种类型的TTY(终端)的使用。需要注意的是这些命名习惯包含了几个历史遗留包袱。其中的一些是Linux所特有的,另一些则是继承自其他系统,还有一些反映了Linux在成长过程中抛弃了原来借用自其它系统的一些习惯。井号(#)在设备名里表示一个无前导零的十进制数。

虚拟控制台(Virtual console)和控制台设备(console device)

虚拟控制台是在系统视频监视器上全屏显示的终端。虚拟控制台被命名为编号从/dev/tty1 开始的 /dev/tty# 。/dev/tty0 是当前虚拟控制台。/dev/tty0 用于在不能使用帧缓冲设备(/dev/fb*)的机器上存取系统视频卡,注意,不要将/dev/console 用于此目的。/dev/console 由内核管理,系统消息将被发送到这里。单用户模式下必须允许 login 使用 /dev/console 。

串行接口

这里所说的"串行接口"是指 RS-232 串行接口和任何模拟这种接口的设备,不管是在硬件(例如调制解调器)还是在软件(例如ISDN驱动)中模拟。在linux中的每一个串行接口都有两个设备名:主设备或呼入(callin)设备、交替设备或呼出(callout)设备。设备类型之间使用字母的大小写进行区分。比如,对于任意字母X,"tty"设备名为 /dev/ttyX# ,而"cu"设备名则为 /dev/cux# 。由于历史原因,/dev/ttyS# 和 /dev/ttyC# 分别等价于 /dev/cua# 和 /dev/cub# 。名称 /dev/ttyQ# 和 /dev/cuq# 被保留为本地使用。

伪终端(PTY)

伪终端用于创建登陆会话或提供其它功能,比如通过 TTY line discipline (包括SLIP或者PPP功能)来处理任意的数据生成。每一个 PTY 都有一个master 端和一个slave端。按照 System V/Unix98 的 PTY 命名方案,所有master端共享同一个 /dev/ptmx 设备节点(打开它内核将自动给出一个未分配的PTY),所有slave端都位于 /dev/pts 目录下,名为 /dev/pts/# (内核会根据需要自动生成和删除它们)。

一旦master端被打开,相应的slave设备就可以按照与 TTY 设备完全相同的方式使用。master设备与slave设备之间通过内核进行连接,等价于拥有 TTY 功能的双向管道(pipe)。

《实用操作系统》实验报告五linux设备管理

《实用操作系统》实验报告 实验报告: 5 实验项目名称:设备管理 班级:学号:姓名: 地点:时间:2013 年11 月13 日 一、实验内容 1、添加硬盘,创建二个主分区、一个扩展分区,二个逻辑分区 注意:ide、scsi 提示:分区、格式化、挂载(fdisk,mkfs,mount) 2、查看常见的设备文件有哪些?(ls /dev ) 常见的设备文件:/dev/hd* IDE接口的硬盘(IDE接口的设备) /dev/sd* SCSI/USB设备/dev/cua* 串口设备/dev/lp* 并口设备/dev/tty* 终端设备/dev/consol 控制台设备/dev/eth* 以太网设备/dev/cdrom IDE光驱/dev/fd* 软驱/dev/audio 音频设备/dev/scd SCSI的光驱/dev/ppp PPP设备/dev/isdn* ISDN设备 3、挂载光盘,查看光盘内容创建挂载点要求:以本人姓名缩写为目录mkdir / 目录/设备挂载mount 空格源设备空格挂载点 4、显示管理System-config-display 5、声卡管理System-config-soundcard 6、打印机管理System-config-printer 7、网卡管理System-config-network 二、实验步骤及结果 1.添加硬盘,创建分区; 在启动虚拟机前,在工具栏中点击“虚拟机”,找到“设置”选项,在左面的硬件中找到硬盘,进行硬盘设备添加,这里有IDE和SCSI两种硬盘类型可供选择添加。完成硬盘添加后即可启动虚拟机进入linux系统。在这我添加了容量相同的硬盘设备类型各一;

Linux设备驱动程序举例

Linux设备驱动程序设计实例2007-03-03 23:09 Linux系统中,设备驱动程序是操作系统内核的重要组成部分,在与硬件设备之间 建立了标准的抽象接口。通过这个接口,用户可以像处理普通文件一样,对硬件设 备进行打开(open)、关闭(close)、读写(read/write)等操作。通过分析和设计设 备驱动程序,可以深入理解Linux系统和进行系统开发。本文通过一个简单的例子 来说明设备驱动程序的设计。 1、程序清单 //MyDev.c 2000年2月7日编写 #ifndef __KERNEL__ #define __KERNEL__//按内核模块编译 #endif #ifndef MODULE #define MODULE//设备驱动程序模块编译 #endif #define DEVICE_NAME "MyDev" #define OPENSPK 1 #define CLOSESPK 2 //必要的头文件 #include //同kernel.h,最基本的内核模块头文件 #include //同module.h,最基本的内核模块头文件 #include //这里包含了进行正确性检查的宏 #include //文件系统所必需的头文件 #include //这里包含了内核空间与用户空间进行数据交换时的函数宏 #include //I/O访问 int my_major=0; //主设备号 static int Device_Open=0; static char Message[]="This is from device driver"; char *Message_Ptr; int my_open(struct inode *inode, struct file *file) {//每当应用程序用open打开设备时,此函数被调用 printk ("\ndevice_open(%p,%p)\n", inode, file); if (Device_Open) return -EBUSY;//同时只能由一个应用程序打开 Device_Open++; MOD_INC_USE_COUNT;//设备打开期间禁止卸载 return 0; } static void my_release(struct inode *inode, struct file *file)

Linux命令大全(设备管理)

设备管理-setleds 名称:setleds 使用权限:一般使用者 使用方式: setleds [-v] [-L] [-D] [-F] [{+|-}num] [{+|-}caps] [{+|-}scroll]说明: 用来设定键盘上方三个LED 的状态。在Linux 中,每一个虚拟主控台都有独立的设定。 参数: -F 预设的选项,设定虚拟主控台的状态。 -D 除了改变虚拟主控台的状态外,还改变预设的状态。 -L 不改变虚拟主控台的状态,但直接改变LED 显示的状态。这会使得LDE 显示和目前虚拟主控台的状态不符合。我们可以在稍后用-L 且不含其它选项的setleds 命令回复正常状态。 -num +num 将数字键打开或关闭。 -caps +caps 把大小写键打开或关闭。 -scroll +scroll 把选项键打开或关闭。 范例: 将数字键打开,其馀二个灯关闭。 # setleds +num -caps -scroll 设备管理-loadkeys 名称: loadkeys 使用权限: 所有使用者

使用方式: loadkeys [ -d --default ] [ -h --help ] [ -q --quiet ] [ -v --verbose [ -v --verbose ]...] [ -m --mktable ] [ -c --clearcompose ] [ -s --clearstrings ] [ filename... ] 使用说明: 这个命令可以根据一个键盘定义表改变linux 键盘驱动程序转译键盘输入过程。详细的说明请参考dumpkeys。 选项: -v --verbose 印出详细的资料,你可以重复以增加详细度。 -q --quiet 不要显示任何讯息。 -c --clearcompose 清除所有composite 定义。 -s --clearstrings 将定串定义表清除。 相关命令: dumpkeys 设备管理-rdev 名称:rdev 使用权限:所有使用者 使用方式:使用这个指令的基本方式是:rdev [-rsvh ] [-o offset ] [ image [value [ offset ] ] ] 但是随著使用者想要设定的参数的不同,底下的方式也是一样: rdev [ -o offset ] [ image [ root_device [ offset ] ] ] swapdev [ -o offset ] [ image [ swap_device [ offset ] ] ] ramsize [ -o offset ] [ image [ size [ offset ] ] ] videomode [ -o offset ] [ image [ mode [ offset ] ] ] rootflags [ -o offset ] [ image [ flags [ offset ] ] ]

Linux设备模型(文档翻译)_(整理文档)

Linux 内核文档翻译- driver-model/bus.txt Bus Types 总线类型 Definition 定义 ~~~~~~~~~~ See the kerneldoc for the struct bus_type. intbus_register(struct bus_type * bus); Declaration 声明 ~~~~~~~~~~~ Each bus type in the kernel (PCI, USB, etc) should declare one static object of this type. They must initialize the name field, and may optionally initialize the match callback. 内核中每个总线类型(PCI、USB 等等)都应该声明一个此类型的静态对象。它们必须初始化该对象的name 字段,然后可选的初始化match 回调函数。 structbus_typepci_bus_type = { .name = "pci", .match = pci_bus_match, }; The structure should be exported to drivers in a header file: 这个结构体应该在头文件中向驱动程序导出: extern struct bus_typepci_bus_type; Registration 注册 ~~~~~~~~~~~~ When a bus driver is initialized, it calls bus_register. This initializes the rest of the fields in the bus object and inserts it into a global list of bus types. Once the bus object is registered, the fields in it are usable by the bus driver. 当初始化一个总线驱动时,将会调用bus_register。这时这个总线对象剩下的字段将被初始化,然后这个对象会被插入到总线类型的一个全局列表里去。一旦完成一个总线对象的注册,那么对于总线驱动来说它里面的字段就已经可用了。

实验九Linux设备管理实验

实验九Linux设备管理实验 一、实验目的: 掌握linux系统重定向、管道操作和设备管理的法。 二、预备知识 1.标准的输入输出和重定向 执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(stdin,通常对应终端的键盘);标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。 用户在输入输出数据时存在以下问题: ●从终端输入数据时,用户输入的数据只能用一次,如果下次再想用这些 数据时就得重新输入。而且在终端上输入时,项输入有误修改起来不是 很便。 ●输出到屏幕上的信息只能看不能动,无法对此输出作更多处理,如将作 为另一命令的输入进行进一步的处理等。 为了解决上述问题,Linux系统为输入输出的传送引入了另外两种机制,即输入输出重定向。输入重定向是指把命令(或可执行程序)的标准输入重定向到指定的文件中。也就是说,输入可以不来自键盘,而来自一个指定的文件。因此,输入重定向主要用于改变一个命令的输入源,告别是改变那些需要大量输入的输入源。输出重定向是批把命令(或可执行程序)的标准输出或标准错误输出重定

向到指定文件中。这样,命令的输出就不显示在屏幕上,而是写入到指定文件中。2.管道 将一个程序或命令的输出作为另一个程序或命令的输入可有两种法,一种是通过一个临时文件将两个命令或程序联系在一起;另一种是Linux所提供的管道功能,这种法比前一种法更好。管道可以把一系列命令连接起来,这就意味着第一个命令的输出会将为第二个命令的输入通过管道传给第二个命令,而第二个命令的输出又作为第三个命令的输入,以此类推。显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中示使用输出重定向)。用户还可以通过使用管道符“|”来建立一个管道行。 3.文件备份和压缩 参见第二章相关的ppt。 三、实验容和实验步骤(实验情况请截图和说明) 1.基本实验 (1)标准输入输出文件使用 通过wc命令统计指定文件包含的行数、单词数和字符数。 实验步骤一:在命令提示符输入ls,显示当前目录下的文件。 [m112013@tan ~]$ ls ch4 ch5 lab1 lab2 lab3 lab4 lab5 lab6 lab7 lab8 lab9 subdir [m112013@tan ~]$ cd lab9 [m112013@tan lab9]$ ls test.c

linux设备模型介绍

第一节基本概念 在设备模型里面,所有的东西都是kobject,这也是linux建立设备设计模型的目的(对比2.4之前),实现了统一的实体;我们理解上,却可以分为两个层次,一个是kobject,一个是管理kobject的kobject(可以把它叫做kset虽然有点绕,但是没有办法了,毕竟就像那个“世界上先有鸡还是先有蛋的哲学问题一下”); kobject结构

1)前面两个顾名思义,就是name了,为什么会有两个呢?k_name就是指向name的,如何知道呢,呵呵,看一下代码 2)kref就是一个内核的原子计数结构,因为涉及内核的操作基本都需要是原子性的,为了大家的方便,kobject就把它包括进来了,所以大家就不必要各自定义自己的计数了(一般情况下:),poll也是类似,把等待队列包括进来; 3)entry 这个名字比较让人误解,其实看它的类型知道是list成员,它就是加入到kset的list 的那个零部件; 4)ktpye 要理解这个成员就稍微麻烦些了,先看一下定义 Default_attrs就是一种比较简单的设置属性文件的方法,它其实跟我们自己调用sysfs_create_file没有什么区别,呵呵,看一下代码就知道了,所以大家基本上可以把它忽略掉:),调用关系为kobject_add->create_dir->populate_dir 把一个忽略掉,剩下的两个就比较重要了;每个对象一般都有多个属性,用面向对象的角度来看,我们可以把对属性的操作抽象为show和store这一对方法,那么多个属性就会有多对show和store的方法;那么,为了实现对这些方法的统一调用,就利用ktype中的sysfs_ops 实现了多态;这样一来,对于sysfs中的普通文件读写操作都是由kobject->ktype->sysfs_ops

linux设备驱动中常用函数

Linux2.6设备驱动常用的接口函数(一) ----字符设备 刚开始,学习linux驱动,觉得linux驱动很难,有字符设备,块设备,网络设备,针对每一种设备其接口函数,驱动的架构都不一样。这么多函数,要每一个的熟悉,那可多难啦!可后来发现linux驱动有很多规律可循,驱动的基本框架都差不多,再就是一些通用的模块。 基本的架构里包括:加载,卸载,常用的读写,打开,关闭,这是那种那基本的咯。利用这些基本的功能,当然无法实现一个系统。比方说:当多个执行单元对资源进行访问时,会引发竞态;当执行单元获取不到资源时,它是阻塞还是非阻塞?当突然间来了中断,该怎么办?还有内存管理,异步通知。而linux 针对这些问题提供了一系列的接口函数和模板框架。这样,在实际驱动设计中,根据具体的要求,选择不同的模块来实现其功能需求。 觉得能熟练理解,运用这些函数,是写号linux设备驱动的第一步。因为是设备驱动,是与最底层的设备打交道,就必须要熟悉底层设备的一些特性,例如字符设备,块设备等。系统提供的接口函数,功能模块就像是工具,能够根据不同的底层设备的的一些特性,选择不同的工具,方能在linux驱动中游刃有余。 最后就是调试,这可是最头疼的事。在调试过程中,总会遇到这样,那样的问题。怎样能更快,更好的发现并解决这些问题,就是一个人的道行咯!我个人觉得: 发现问题比解决问题更难! 时好时坏的东西,最纠结! 看得见的错误比看不见的错误好解决! 一:Fops结构体中函数: ①ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 用来从设备中获取数据. 在这个位置的一个空指针导致 read 系统调用以-EINVAL("Invalid argument") 失败. 一个非负返回值代表了成功读取的字节数( 返回值是一个 "signed size" 类型, 常常是目标平台本地的整数类型). ②ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 发送数据给设备. 如果 NULL, -EINVAL 返回给调用 write 系统调用的程序. 如果非负, 返回值代表成功写的字节数 ③loff_t (*llseek) (struct file *, loff_t, int); llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值. loff_t 参数是一个"long offset", 并且就算在 32位平台上也至少 64 位宽. 错误由一个负返回值指示. 如果这个函数指针是 NULL, seek 调用会以潜在地无法预知的方式修改 file 结构中的位置计数器( 在"file 结构" 一节中描述). ④int (*open) (struct inode *, struct file *);

linux设备管理命令

linux设备管理命令 1.1 stty [语法]: stty [-a] [-g] [选项] [说明]: 本命令设置终端,无参数时报告终端设置,本命令功能十分强大,应谨慎使用,下面仅介绍部分常用功能 ?-a 显示当前终端所有设置 ?-g 以能作为 stty 命令参数的方式显示终端设置以下是终端常用设置,在设置前加-表示清除设置: o1.控制方式,ispeed 0 110 300 600 1200 1800 2400 4800 9600 19200 38400,本命令设置终端输入波特率,若为0则使用缺省波 特率。例如 stty ispeed 9600 ospeed 0 110 300 600 1200 1800 2400 4800 9600 19200 38400本命令设置终端输出波特率,参看 ispeed。 o2.输入方式 ?ingbrk(-ignbrk) 忽略(不忽略)中断(BREAK) ?brkint(-brkint) 设置(清除)信号INTR为中断信号 ?inlcr(-inlcr) 将换行转换(不转换)成回车 ?icrnl( -icrnl) 将回车转换(不转换)成换行 ?igncr(-ignrc) 忽略(不忽略)回车 ?iuclc( -iuclc) 将大写字母转换(不转换)成小写字母o3.输出方式 ?olcut(-olcut) 将小写字母转换(不转换)为大写字母 ?onlcr(-onlcr) 输出时将换行符转换(不转换)为回车换行 ?ocrnl(-ocrnl) 输出时将回车符转换(不转换)为换行符o4.本地方式 ?echo (-echo) 设置(清除)回显 ?stwrap(-stwrap) 截断(不截断)大于79个字符的行 ?echoctl(-echoctr) 将控制键回显为^ 1.2 tty [语法]: tty [说明]: 显示出终端的设备名 [例子]: tty 1.3 lp [语法]: lp 文件... [说明]: 将文件送打印机打印 [例子]: lp myfile将文件myfile 送打印机输出 1.4 lpstat [语法]: lpstat [选项] [打印任务号] [说明]: 显示打印机状态,选项的意义如下:

Linux设备模型 热插拔、mdev 与 firmware

Linux设备驱动程序学习(15) -Linux设备模型(热插拔、mdev 与firmware) 热插拔 有2 个不同角度来看待热插拔: 从内核角度看,热插拔是在硬件、内核和内核驱动之间的交互。 从用户角度看,热插拔是内核和用户空间之间,通过调用用户空间程序(如hotplug、udev 和mdev)的交互。当需要通知用户内核发生了某种热插拔事件时,内核才调用这个用户空间程序。 现在的计算机系统,要求Linux 内核能够在硬件从系统中增删时,可靠稳定地运行。这就对设备驱动作 者增加了压力,因为在他们必须处理一个毫无征兆地突然出现或消失的设备。 热插拔工具 当用户向系统添加或删除设备时,内核会产生一个热插拔事件,并在/proc/sys/kernel/hotplug文件里查找处理设备连接的用户空间程序。这个用户空间程序主要有 hotplug:这个程序是一个典型的bash 脚本,只传递执行权给一系列位于/etc/hot-plug.d/ 目录树的程序。hotplug 脚本搜索所有的有 .hotplug 后缀的可能对这个事件进行处理的程序并调用它们, 并传递给它们许多不同的已经被内核设置的环境变量。(基本已被淘汰,具体内容请参阅《LDD3》) udev :用于linux2.6.13或更高版本的内核上,为用户空间提供使用固定设备名的动态/dev目录的解 决方案。它通过在sysfs 的/class/ 和/block/ 目录树中查找一个称为dev 的文件,以确定所创建的 设备节点文件的主次设备号。所以要使用udev,驱动必须为设备在sysfs中创建类接口及其dev属性文件,方法和sculld模块中创建dev属性相同。udev的资料网上十分丰富,我就不在这废话了,给出以 下链接有兴趣的自己研究:

Linux设备驱动程序简介

第一章Linux设备驱动程序简介 Linux Kernel 系统架构图 一、驱动程序的特点 ?是应用和硬件设备之间的一个软件层。 ?这个软件层一般在内核中实现 ?设备驱动程序的作用在于提供机制,而不是提供策略,编写访问硬件的内核代码时不要给用户强加任何策略 o机制:驱动程序能实现什么功能。 o策略:用户如何使用这些功能。 二、设备驱动分类和内核模块 ?设备驱动类型。Linux 系统将设备驱动分成三种类型 o字符设备 o块设备 o网络设备 ?内核模块:内核模块是内核提供的一种可以动态加载功能单元来扩展内核功能的机制,类似于软件中的插件机制。这种功能单元叫内核模块。 ?通常为每个驱动创建一个不同的模块,而不在一个模块中实现多个设备驱动,从而实现良好的伸缩性和扩展性。 三、字符设备 ?字符设备是个能够象字节流<比如文件)一样访问的设备,由字符设备驱动程序来实现这种特性。通过/dev下的字符设备文件来访问。字符设备驱动程序通常至少需要实现 open、close、read 和 write 等系统调用 所对应的对该硬件进行操作的功能函数。 ?应用程序调用system call<系统调用),例如:read、write,将会导致操作系统执行上层功能组件的代码,这些代码会处理内核的一些内部 事务,为操作硬件做好准备,然后就会调用驱动程序中实现的对硬件进 行物理操作的函数,从而完成对硬件的驱动,然后返回操作系统上层功 能组件的代码,做好内核内部的善后事务,最后返回应用程序。 ?由于应用程序必须使用/dev目录下的设备文件<参见open调用的第1个参数),所以该设备文件必须事先创建。谁创建设备文件呢? ?大多数字符设备是个只能顺序访问的数据通道,不能前后移动访问指针,这点和文件不同。比如串口驱动,只能顺序的读写设备。然而,也 存在和数据区或者文件特性类似的字符设备,访问它们时可前后移动访

Linux统一设备管理平台platform之设备注册流程V2版-李枝果

Linux lizhiguo0532@https://www.360docs.net/doc/cd4570106.html, --------------------------------------------------------------------------------------------------------------------- https://www.360docs.net/doc/cd4570106.html,/sz_farsight ---------------------------------------------------------------------------------------------------------------------- linux-2.6.14 1. linux2.6 platform_device platform_driver Linux Platform_device Platform_driver platform driver device driver ( driver_register ) platform platform device 2.s3c2410 3. a. :include\linux\ioport.h struct resource { const char *name; /* */ unsigned long start, end; /* cpu * start cpu * end */ unsigned long flags; /* */ /* */ /* */ struct resource *parent, *sibling, *child; /* */ }; /* * ,

如何实现Linux设备驱动模型

文库资料?2017 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 如何实现Linux 设备驱动模型 设备驱动模型,对系统的所有设备和驱动进行了抽象,形成了复杂的设备树型结构,采用面向对象的方法,抽象出了device 设备、driver 驱动、bus 总线和class 类等概念,所有已经注册的设备和驱动都挂在总线上,总线来完成设备和驱动之间的匹配。总线、设备、驱动以及类之间的关系错综复杂,在Linux 内核中通过kobject 、kset 和subsys 来进行管理,驱动编写可以忽略这些管理机制的具体实现。 设备驱动模型的内部结构还在不停的发生改变,如device 、driver 、bus 等数据结构在不同版本都有差异,但是基于设备驱动模型编程的结构基本还是统一的。 Linux 设备驱动模型是Linux 驱动编程的高级内容,这一节只对device 、driver 等这些基本概念作介绍,便于阅读和理解内核中的代码。实际上,具体驱动也不会孤立的使用这些概念,这些概念都融合在更高层的驱动子系统中。对于大多数读者可以忽略这一节内容。 1.1.1 设备 在Linux 设备驱动模型中,底层用device 结构来描述所管理的设备。device 结构在文件中定义,如程序清单错误!文档中没有指定样式的文字。.1所示。 程序清单错误!文档中没有指定样式的文字。.1 device 数据结构定义 struct device { struct device *parent; /* 父设备 */ struct device_private *p; /* 设备的私有数据 */ struct kobject kobj; /* 设备的kobject 对象 */ const char *init_name; /*设备的初始名字 */ struct device_type *type; /* 设备类型 */ struct mutex mutex; /*同步驱动的互斥信号量 */ struct bus_type *bus; /*设备所在的总线类型 */ struct device_driver *driver; /*管理该设备的驱动程序 */ void *platform_data; /*平台相关的数据 */ struct dev_pm_info power; /* 电源管理 */ #ifdef CONFIG_NUMA int numa_node; /*设备接近的非一致性存储结构 */ #endif u64 *dma_mask; /* DMA 掩码 */ u64 coherent_dma_mask; /*设备一致性的DMA 掩码 */ struct device_dma_parameters *dma_parms; /* DMA 参数 */ struct list_head dma_pools; /* DMA 缓冲池 */ struct dma_coherent_mem *dma_mem; /* DMA 一致性内存 */ /*体系结构相关的附加项*/ struct dev_archdata archdata; /* 体系结构相关的数据 */ #ifdef CONFIG_OF

linux设备驱动

Linux设备驱动 操作系统的目的之一就是将系统硬件设备细节从用户视线中隐藏起来。例如虚拟文件系统对各种类型已安装的文件系统提供了统一的视图而屏蔽了具体底层细节。本章将描叙Linux核心对系统中物理设备的管理。 CPU并不是系统中唯一的智能设备,每个物理设备都拥有自己的控制器。键盘、鼠标和串行口由一个高级I/O芯片统一管理,IDE控制器控制IDE硬盘而SCSI控制器控制SCSI硬盘等等。每个硬件控制器都有各自的控制和状态寄存器(CSR)并且各不相同。例如Adaptec 2940 SCSI控制器的CSR与NCR 810 SCSI控制器完全不一样。这些CSR被用来启动和停止,初始化设备及对设备进行诊断。在Linux中管理硬件设备控制器的代码并没有放置在每个应用程序中而是由内核统一管理。这些处理和管理硬件控制器的软件就是设备驱动。Linux 核心设备驱动是一组运行在特权级上的内存驻留底层硬件处理共享库。正是它们负责管理各个设备。 设备驱动的一个基本特征是设备处理的抽象概念。所有硬件设备都被看成普通文件;可以通过和操纵普通文件相同的标准系统调用来打开、关闭、读取和写入设备。系统中每个设备都用一种特殊的设备相关文件来表示(device special file),例如系统中第一个IDE硬盘被表示成/dev/hda。块(磁盘)设备和字符设备的设备相关文件可以通过mknod命令来创建,并使用主从设备号来描叙此设备。网络设备也用设备相关文件来表示,但Linux寻找和初始化网络设备时才建立这种文件。由同一个设备驱动控制的所有设备具有相同的主设备号。从设备号则被用来区分具有相同主设备号且由相同设备驱动控制的不同设备。例如主IDE硬盘的每个分区的从设备号都不相同。如/dev/hda2表示主IDE 硬盘的主设备号为3而从设备号为2。Linux通过使用主从设备号将包含在系统调用中的(如将一个文件系统mount到一个块设备)设备相关文件映射到设备的设备驱动以及大量系统表格中,如字符设备表,chrdevs。 Linux支持三类硬件设备:字符、块及网络设备。字符设备指那些无需缓冲直接读写的设备,如系统的串口设备/dev/cua0和/dev/cua1。块设备则仅能以块为单位读写,典型的块大小为512或1024字节。块设备的存取是通过

设备管理--Linux设备驱动程序安装

集美大学计算机工程学院实验报告 课程名称:操作系统班级:xxx实验成绩: 指导教师:姓名:xxx ( 学号:xxxx上机实践日期:xxx 实验项目名称: 设备管理——Linux设备驱动程序安装 实验项目编号:组号:上机实践时间: 2 学时~ 一、目的(本次实验所涉及并要求掌握的知识点) 1.认识Linux的设备的种类和设备工作方式; 2.理解设备驱动程序的工作原理; 3.掌握设备驱动程序的编写规范,能编写并安装简单的设备驱动程序。 二、实验内容与设计思想(设计思路、主要数据结构、主要代码结构、主要代码段分析、电路图) 实验内容: ¥ 在Linux系统中,编写一个简单的字符型设备驱动程序模块,设备具有独占特性,可执行读和写操作,相关系统调用为open, close, read, write,open和close分别相当于请求和释放设备,read和write内容保存在设备模块内的缓冲区中。设备模块可动态注册和卸载,并建立与之对应的特殊文件/dev/mydev。 实验设计: 1.按照要求编写设备驱动模块,同时编写一个测试程序 2.分别对其编译,注意编译时的项 3.设备模块加载 4.创建特殊文件 5.分析执行结果 6.设备模块卸载 < 三、实验使用环境(本次实验所使用的平台和相关软件) Linux 四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析) LINUX_VERSION_CODE is * the code (as per KERNEL_VERSION) of this version. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0) < #include /* for put_user */ #endif #define SUCCESS 0 #define DEVICE_NAME "kueng_char_dev"

Linux设备模型:基本概念

Linux设备模型:基本概念 1. 前言 在“Linux内核的整体架构”中,蜗蜗有提到,由于Linux支持世界上几乎所有的、不同功能的硬件设备(这是Linux的优点),导致Linux内核中有一半的代码是设备驱动,而且随着硬件的快速升级换代,设备驱动的代码量也在快速增长。个人意见,这种现象打破了“简洁就是美”的理念,是丑陋的。它导致Linux内核看上去非常臃肿、杂乱、不易维护。但蜗蜗也知道,这不是Linux的错,Linux是一个宏内核,它必须面对设备的多样性,并实现对应的驱动。 为了降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型(也称作Driver Model)的概念。设备模型将硬件设备归纳、分类,然后抽象出一套标准的数据结构和接口。驱动的开发,就简化为对内核所规定的数据结构的填充和实现。 本文将会从设备模型的基本概念开始,通过分析内核相应的代码,一步一步解析Linux设备模型的实现及使用方法。 2. Linux设备模型的基本概念 2.1 Bus, Class, Device和Device Driver的概念 下图是嵌入式系统常见的硬件拓扑的一个示例: 硬件拓扑描述Linux设备模型中四个重要概念中三个:Bus,Class和Device(第四个为Device Driver,后面会说)。 Bus(总线):Linux认为(可以参考include/linux/device.h中struct bus_type的注释),总线是CPU和一个或多个设备之间信息交互的通道。而为了方便设备模型的抽象,所有的设备都应连接到总线上(无论是CPU内部总线、虚拟的总线还是“platform Bus”)。 Class(分类):在Linux设备模型中,Class的概念非常类似面向对象程序设计中的Class (类),它主要是集合具有相似功能或属性的设备,这样就可以抽象出一套可以在多个设

Linux设备驱动程序说明介绍

Linux设备驱动程序简介 Linux是Unix操作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环境下的驱动程序有很大的区别。在Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大,但是支持函数少,只能依赖kernel 中的函数,有些常用的操作要自己来编写,而且调试也不方便。本人这几周来为实验室自行研制的一块多媒体卡编制了驱动程序,获得了一些经验,愿与Linux fans共享,有不当之处,请予指正。 以下的一些文字主要来源于khg,johnsonm的Write linux device driver,Brennan's Guide to Inline Assembly,The Linux A-Z,还有清华BBS上的有关device driver的一些资料. 这些资料有的已经过时,有的还有一些错误,我依据自己的试验结果进行了修正. 一、Linux device driver 的概念 系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口.设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作.设备驱动程序是内核的一部分,它完成以下的功能: 1.对设备初始化和释放. 2.把数据从内核传送到硬件和从硬件读取数据. 3.读取应用程序传送给设备文件的数据和回送应用程序请求的数据. 4.检测和处理设备出现的错误. 在Linux操作系统下有两类主要的设备文件类型,一种是字符设备,另一种是块设备.字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作.块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待. 已经提到,用户进程是通过设备文件来与实际的硬件打交道.每个设备文件都都有其文件属性(c/b),表示是字符设备还蔤强樯璞?另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们.设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序. 最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度.也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作.如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck. 读/写时,它首先察看缓冲区的内容,如果缓冲区的数据 如何编写Linux操作系统下的设备驱动程序 二、实例剖析 我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理.把下面的C代码输入机器,你就会获得一个真正的设备驱动程序.不过我的kernel是2.0.34,在低版本的kernel上可能会出现问题,我还没测试过. [code]#define __NO_VERSION__

第一章(linux设备驱动程序).doc

第1章Linux内核简介 世界各地都有人在钻研Linux内核,大多是在写设备驱动程序。尽管每个驱动程序都不一样,而且你还要知道自己设备的特殊性,但是这些设备驱动程序的许多原则和基本技术技巧都是一样的。通过本书,可以学会写自己的设备驱动程序,并且可以钻研内核的相关部分。本书涉及到的是设备无关编程技巧,不会将例子跟特殊设备绑定在一起。 本章没有实际编写代码。但我要介绍一些关于Linux内核的背景概念,这样到我们稍后开始介绍实际编程时,就很顺利了。 当你学习编写驱动程序的时候,你也会发现很多关于Linux内核的知识,这对理解你机器怎么工作很有帮助,并且还可以知道为什么你的机器没有希望的那么快,或者为什么不按照你象要它做的那样做。我们会逐渐介绍一些新概念,先从简单的驱动程序开始,每介绍一些新概念都会看到相关例子代码,这些代码都不需要特殊硬件。 驱动程序作者的作用 作为一个程序员,你可以选择自己的驱动程序,在编程所需时间和结果的灵活性之间做个可以接受的权衡。尽管说驱动程序的灵活性看起来有那么点怪,我喜欢这个词是因为它强调了设备驱动程序提供的是机制,而不是策略。 机制和策略之间的差别是Unix设计背后最好的点子之一。实际编程中遇到的大多数问题都可以被划分成两个部分:“需要作什么”(机制)和“这个程序怎么用”(策略)。如果这两个主题是由程序不同部分来承担的,或者是由不同的程序组合一起承担的,那么这个软件包就很容易开发,也很适合特殊需求。 举个例子,Unix的图形显示管理在X服务器和窗口管理器之间划了一道线,X服务器了解硬件并给用户程序提供唯一的接口,而窗口管理器实现特殊的策略并不需要知道硬件的任何信息。人们可以在不同硬件上使用同样的窗口管理器,并且不同用户在同一台工作站上可以使用不同的设置。另一个例子是TCP/IP的网络分层结构:操作系统提供抽象的套接字操作,是设备无关的,不同服务器主管这个服务。另外,ftpd服务器提供文件传输机制,而用户可以使用任何客户端程序;命令行的客户端和图形化界面的客户端都存在,并且谁都可以为传输文件写一个新的用户界面。 只要涉及到驱动程序,就会运用这样的功能划分。软盘驱动程序是设备无关的——这不仅表现在磁盘是一个连续读写的字节数组上。如何使用设备是应用程序要做的事:tar要连续地写数据,而mkfs则为要安装的设备做准备工作,mcopy依赖于设备上存在的特殊数据结构。在写驱动程序时,程序员应该特别留心这样的基本问题:我们要写内核代码访问硬件,但由于不同用户有不同需要,我们不能强迫用户采用什么样的特定策略。设备驱动程序应该仅仅处理硬件,将如何使用硬件的问题留给应用程序。如果在提供获得硬件能力的同时没有增加限制,我们就说驱动程序是灵活的。不过,有时必须要作一些策略决策。 可以从不同侧面来看你的驱动程序:它是位于应用层和实际设备之间的软件。驱动程序的程序员可以选择这个设备应该怎样实现:不同的驱动程序可以提供不同的能力,甚至相同的设备也可以提供不同能力。实际驱动程序设计应该是在众多需求之间的一个平衡。例如,不同程序可以同时使用同一个设备,而驱动程序的开发者可以完全自由地决定如何处理同步机制。你可以实现到设备上的内存映射,而完成独立于硬件的具体能力,或者你可以提供给用

LINUX设备模型

LINUX设备模型 https://www.360docs.net/doc/cd4570106.html,/blog/static/6044209320094159558397/看了一段时间的驱动编程,从LDD3的hello wrod到后来的字符设备以至于更加复杂的驱动,越看越是觉得对linux驱动的结构不清楚,越看越是迷糊。于是就停下脚步搜索一下资料理一下头绪: 以下四个方面来总结一些内容: 1.底层数据结构:kobject,kset. 2.linux设备模型层次关系:bus_type,device,device_driver. 3.集成:PC I设备驱动模型实例及设备,设备驱动注册源码的简单分析. 4.面向对象的思想在linux设备模型中的应用分析. 一、底层数据结构:kobject,kset 先说说模型的意义: 总体来说是为了系统地管理所有设备。 在具体实现方面分两个层次: 一是底层数据结构来实现基本对象及其层次关系:kobjects和ksets。 二是基于这两个底层数据结构上实现的设备模型:总线,设备,驱动。 kobject 结合面向对象的思维。这个kobject属于最基础的结构,也就是最高抽象层(有点像java中的Cobject类)。任何一个设备模型如总线,设备,驱动都属于一个kobject 。在实现上这种派生关系就是在结构体中包含一个kobject的变量。 这个在层次上处理最顶层的kobject结构提供了所有模型需要的最基本的功能: 1 引用计数用于内核维护其存在与消亡 2 sysfs表示每个sys/下的对象对应着一个kobject。 3 热拔插事件处理。处理设备的热拔插事件。 Kobjects 在内核中对应有一套申请,初始化,添加,注册,计数操作,释放等函数 struct kobject { const char * k_name; 名 char name[KOBJ_NAME_LEN]; struct kref kref; 计数 struct list_head entry; 用于连接到同类kobjects的链表 struct kobject * parent; 用于实现层次,指向其父对象。 struct kset * kset; 用于实现层次,所属的集合 struct kobj_type * ktype; 指向对象的类型。 struct dentry * dentry; 指示在sysfs 中的目录项 wait_queue_head_t poll; }; (linux 2.6.18)

相关文档
最新文档