16 FreeBSD连载:设备文件

设备文件对于每种硬件设备,系统内核有相应的设备驱动程序负责对它的处理 。而在Unix中,使用设备文件的方式来表示硬件设备,每种设备驱动程序都被抽象为设备文件的形式,这样就给应用程序一个一致的文件界面,方便应用程序和操作系统之间的通信 。所有的设备文件都放置在/dev目录下 。
$ ls -l /dev/rfd0 /dev/fd0
brw-r-----9 root operator 2, 0 Nov 12 13:32 /dev/fd0
crw-r-----9 root operator 9, 0 Nov 12 13:32 /dev/rfd0
在上面的列表中可以看到原来显示文件大小的地方,现在改为显示两个用逗号分隔的数字 。这是系统用来表示设备的两个重要的序号,第一个为主设备号(major number),用来表示设备使用的硬件驱动程序在系统中的序号;第二个为从设备号(minor number),硬件驱动程序使用它来区分不同的设备和判断如何进行处理 。FreeBSD下主设备号用8位表示,而从设备号用24位来表示 。事实上设备文件的名字并不重要,重要的是这两个设备号,操作系统使用它确定硬件驱动程序,并与硬件驱动程序进行通信 。
磁盘和块设备文件
在Unix下将设备分为两种,块设备和字符设备,其中块设备主要用于随机存取的目的,磁盘为这一类设备的代表,而字符设备用于顺序存取的目的,例如磁带或终端设备 。
磁盘设备的命名方式在前一章中提到过,磁盘设备由磁盘名、磁盘的序号、分区的序号、以及FreeBSD子分区的序号来表示,例如在设备wd0s1a中,wd为驱动程序,此后为设备序号,0表示为这个驱动程序的第一个设备,Unix习惯上从0开始计数,第三部分的分区序号为s1,注意这里为第一个分区,因为s1是从1开始向下排列的,与一般Unix的习惯不同,这是因为分区的概念是一个Dos概念,因此这里也使用与DOS相对应的顺序,最后一个a为FreeBSD子分区的顺序,每个UFS基本分区可以有8个子分区,这8个分区按照习惯用于不同的目的,例如wd0s1a用于根文件系统,wd0s1b用做交换分区,使用wd0s1c表示整个硬盘分区wd0s1 。因此可以将fd0c用于对整个软盘fd0进行存取,wcd0c用于对整个光盘wcd0进行存取等 。
传统名字,例如wd0a,可以用于表示第一个UFS分区上的a子分区,如wd0s1a 。一般一个硬盘上只有一个UFS分区,因此可以直接使用传统名字标识磁盘分区 。
在使用ls命令列表时,系统使用c(character)标识一个字符设备文件,使用b(block)标识块设备文件 。
$ ls -l /dev/*wd0s1
crw-r----- 1 root operator 3, 131072 Oct 31 19:59 /dev/rwd0s1
brw-r----- 1 root operator 0, 131072 Oct 31 19:59 /dev/wd0s1
虽然硬盘设备为块设备,用于随机存取的目的 。但它也可以被顺序存取,这种方式称为raw方式 。使用raw方式存取硬盘,就需要一个对应的字符类型的设备文件,对应wd0s1硬盘设备的字符类型硬盘设备为rwd0s1,设备名中第一个字母使用r表示对硬盘的raw方式顺序存取 。
由于设备文件就代表了整个设备,就可以使用FreeBSD的标准命令以raw方式直接操作设备文件,从而直接访问硬件设备 。利用这种方式,能完成很多有用的工作,但是这种方式也非常危险,例如对硬盘设备文件的操作失误会破坏整个硬盘的数据 。幸好大部分直接访问设备的操作都为读取相应数据的操作,而不需要写入磁盘设备 。
当某个设备不可使用,则其对应的设备文件也不能正常访问,因此直接访问设备文件可以判断对应的设备是否真正正常 。例如,判断连接到第一个串口,ttyd0上的鼠标是否正常工作,使用命令 “cat

推荐阅读