mknod 详解

     网上找了很多关于mknod的文章,但每一篇都有点不足,故我在这里整合了一篇如下:

下文转自:http://fengjixuchui.blog.51cto.com/854545/462275

    创建特殊文件。  

 mknod [options] name {b|c} major minor

  创建 FIFO(已命名的管道)

  mknod [options] name { p }

  GNU 选项(缩写):

  [-m mode] [--help] [--version] [--]

  描述

        mknod 用指定名称产生一个FIFO(命名管道),字符专用或块专用文件。

  文件系统中的一个专用文件存贮着三种信息(布朗型、整型、整型)。布朗型在字符文件与块文件之间作出选择,两个整型是主、次设备号。

  通常,一个专用文件并不在磁盘上占用空间,仅仅是为操作系统提供交流,而不是为数据存贮服务。一般地,专用文件会指向一个硬件设备(如:磁盘、磁带、打印机、虚拟控制台)或者操作系统提供的服务(如:/dev/null, /dev/random)。

  块文件通常类似于磁盘设备(在数据可以被访问的地方赋予一个块号,意味着同时设定了一个块缓存)。所有其他设备都是字符文件。(以前,两种文件类型间是有差别的。比如:字符文件I/O没有缓存,而块文件则有。)


  mknod 命令建立一个目录项和一个特殊文件的对应索引节点。第一个参数是 Name 项设备的名称。选择一个描述性的设备名称。mknod 命令有两种形式,它们有不同的标志。

  第一种形式中,使用了b 或 c 标志。b 标志表示这个特殊文件是面向块的设备(磁盘、软盘或磁带)。c 标志表示这个特殊文件是面向字符的设备(其他设备)。

  第一种形式的最后两个参数是指定主设备的数目,它帮助操作系统查找设备驱动程序代码,和指定次设备的数目,也就是单元驱动器或行号,它们是十进制或八进制的。一个设备的主要和次要编号由该设备的配置方法分配,它们保存在 ODM 中的 CuDvDr 类里。在这个对象类中定义了主要和次要编号以确保整个系统设备定义的一致性,这是很重要的。

  在 mknod 命令的第二种形式中,使用了 p 标志来创建 FIFO(已命名的管道)。

GNU版本还允许使用u('unbufferd'非缓冲化),以保持与C语言的一致。

  当创建一个块文件或字符文件时,主、次设备号必须在文件类型参数后给出。(十进制或八进制以0开头;GNU 版本还允许使用以0x开头的十六进制)缺省地,所产生的文件模式为0666('a+rw')。

  选项

  -m mode, --mode=mode

  为新建立的文件设定模式,就象应用命令chmod一样,以后仍然使用缺省模式建立新目录。

  GNU 标准选项

  --help

  在标准输出上显示使用信息并顺利退出。

  --version

  在标准输出上显示版本信息并顺利退出

  --

  终端选项列表。




标志

  

b

表示特殊文件是面向块的设备(磁盘、软盘或磁带)。

c

表示特殊文件是面向字符的设备(其他设备)。

p

创建 FIFO(已命名的管道)。

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

  c.创建虚拟设备(dev),日志记录的时候有的选项可能用到它们。在默认情况下,是使用/dev目录下的文件,但是由于我们需要把DNS限制到一个目录,所以必须完全把/dev下用到的文件(或者说设备)模拟过来才可以。

  ls -lL /dev/zero /dev/null /dev/random

  看到类似

  crw-rw-rw- 1 root root 1, 3 2003-09-15 /dev/null

  crw-r--r-- 1 root root 1, 8 2003-09-15 /dev/random

  crw-rw-rw- 1 root root 1, 5 2003-09-15 /dev/zero

  这样的,将其中的1,3这样的数字记录下来,这表示主设备号和次设备号(一般来说主设备号用来区分设备的种类;次设备号则是为了作唯一性区分,标明不同属性——注意,在unix系统中是把设备也当作文件来对待的),在redhat 9下,ls加不加-L参数都无所谓,但是在Solaris下则一定要加上才可以显示。

  mknod dev/null c 1 3

  mknod dev/zero c 1 5

  mknod dev/random c 1 8

        主、次设备号可在内核源代码的./Documentation/devices.txt里查到,mknod 可为这些指定的设备创建节点,当然节点的位置不是一定要在/dev下,但是为了便于管理一般都是指定/dev。驱动程序是根据主、次设备号定位的,但是你的应用程序open一个设备时,一定要是你指定的节点位置。例如:

  mknod /dev/input/mouse0 c 13 32

  也可以

  mknod /tmp/mymouse c 13 32



==========================================================================================

     看到这边之时,你应该对mknod比较了解了,接下来我们来看看和mknod紧密联系的 设备文件


下文摘自:http://woxihuanpes.blog.163.com/blog/static/124232198200991551511956/


主设备号是由/usr/src/linux/include/linux/major.h定义的,如下定义了一个DOC设备:
#define IGEL_FLASH_MAJOR 62

假如有一个命令mknod doc b 62 0 :
其中的doc为定义的名字,b指块设备,0指的是整个DOC。如果把0换为1,则1指的是DOC的第一个分区。2是第2个,依次类推。

至于mknod console c 5 1 的意思也很相似:
console是设备的名字
c指字符设备
5是该设备在major.h中定义的标记
1是第一个子设备

mknod console c 5 1
console为设备文件名,自己随便取
c是指字符型设备 (可选b,块设备)
5是主设备号 /dev/devices里面记录现有的设备
找个没有用的就可以了
1是次设备号,当你要给两个同样的设备上一个驱动的时候就要分了,从0开始,1就是第二个了


设备文件

对于每种硬件设备,系统内核有相应的设备驱动程序负责对它的处理。而在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位来表示。事实上设备文件的名字并不重要,重要的是这两个设备号,操作系统使用它确定硬件驱动程序,并与硬件驱动程序进行通信。

1) 磁盘和块设备文件
在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 </dev/ttyd0” 来查看ttyd0上的输入数据,如果连接的有鼠标且工作正常,那么在移动鼠标的同时屏幕上就会显示出接收到的杂乱数据。如果没有反应,说明鼠标工作不正确。

但是如果存在其他的程序接管了这个设备,有可能就不能得到正确的结果。例如系统运行了moused,由moused控制了鼠标端口,那么”cat </dev/ttyd0”就不能正常工作,而 “cat < /dev/sysmouse” 会给出答案。

cat或其他命令,没有控制具体接收到数据的多少,更有效的系统工具是dd,它能精确输入输出一定数量的数据。例如:

# dd if=/dev/rwd0 of=mbr count=1 bs=512

这将以512字节为单位,读取硬盘wd0上一个单位的数据,保存到名字为mbr的文件中,通常这是硬盘wd0上的主引导扇区。

2) 设备文件的创建
通常情况下,安装系统时已经创建了常用的设备文件,可以直接访问这些设备文件来访问设备。但在用户重新定制内核,并添加了新硬件驱动程序之后,新驱动程序对应的设备文件就可能不存在。在FreeBSD中,最常见的例子就是在内核中增加声卡的驱动程序时,就需要创建相应设备文件。

创建设备文件的基本方式是使用mknod,但是必须知道该设备的正确设备号才可以。另一种简单的方式是使用/dev目录下的shell程序 MAKEDEV来完成,MAKEDEV实质上就是记录了很多设备的名字与其设备号之间的关系的程序,因此它能使用正确的设备号来创建设备。首先进入 /dev目录,然后再执行MAKEDEV。

# cd /dev

# sh MAKEDEV snd0

MAKEDEV将使用设备名作参数创建设备文件,同时也创建这个设备文件依赖的其他相关设备文件。MAKEDEV的参数,并不一定为创建的设备文件名。例如建立 “MAKEDEV vty8” 将建立ttyv0到ttyv7共8个设备文件,使用 “MAKEDEV wd1s1a” 命令,将建立 wd1、wd1s1、wd1s2等,以及wd1s1a、wd1s1b等设备文件。也可以使用all做MAKEDEV的参数,这将首先清除/dev目录下的所有设备文件,然后MAKEDEV创建所有预设的设备文件。一般情况下这将创建足够多的设备文件,其中的大部分设备文件在具体的系统中不会用得到。

如果对一个系统中没有(或者即使有但内核没有支持或探测到)的设备对应的设备文件进行操作,则系统返回Device not configured的错误信息。

MAKEDEV将使用mknod和对应设备的正确参数,包括字符或块设备、主设备号和从设备号来建立相应的设备文件。管理员也可以直接使用 mknod创建设备文件,但这就必须将这些设备参数统统指定正确才行。因此除非对系统中的硬件驱动程序特别熟悉,一般不直接使用mknod来创建设备文件。

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

 

[root@can]# ll /dev/hd
hda   hda1  hda2  hda3  hda4  hda5  hdc
[root@can]# ll /dev/hda
brw-r----- 1 root disk 3, 0 2008-12-18 /dev/hda
[root@can]# ll /dev/hda4
brw-r----- 1 root disk 3, 4 2008-12-18 /dev/hda4
[root@can]#


=================================================================================


  下面是某个网友利用mknod成功解决找不到swap分区的问题。

  开了一个大程序,用free看看内存是用,却显示如下

  linuxman:~ # free

  total used free shared buffers cached

  Mem: 248380 243800 4580 0 2928 53344

  -/+ buffers/cache: 187528 60852

  Swap: 0 0 0

  怪了,swap怎么是零? 用#swapon -a,却说是没有这个文件/dev/hda7!

  关于swap,我的fatab文件中有一行是这样的:

  /dev/hda7 swap swap pri=42 0 0

  于是:#ls /dev/hda*,果然没有hda7这个block设备!那就创建一个!

  我就用#mknod /dev/hda7 b 3 7,再chmod 和 chgrp 一下就可以了!

  这样#ls /dev/hda7就显示这样了:

  brw-rw---- 1 root disk 3, 7 2005-04-12 07:00 /dev/hda7

  然后再#swapon -a就可以了;#free显示

  total used free shared buffers cached

  Mem: 248380 242368 6012 0 5596 55304

  -/+ buffers/cache: 181468 66912

  Swap: 334616 0 334616


  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值