mknod用法以及主次设备号【转】

转自:http://www.cnblogs.com/hnrainll/archive/2011/06/10/2077583.html

mknod 

用途

  创建特殊文件。

  mknod Name { b | c } Major Minor

  创建 FIFO(已命名的管道)

  mknod Name { p }

  描述

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

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

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

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

标志

  


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

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

  mknod命令详解

  mknod [options] name {bc} major minor

  mknod [options] name p

  GNU 选项(缩写):

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

  描述

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

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

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

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

  mknod命令就是用来产生这种类型文件的。

  以下参数指定了所产生文件的类型:

  b create a block (buffered) special file

  c, u create a character (unbuffered) special file

  p create a FIFO

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

  当创建一个块文件或字符文件时,主、次设备号必须在文件类型参数后给出。但当指定一个p(FIFO)类型时,主次设备号必须省略。(设备号默认是以十进制表示;八进制以0开头;GNU 版本还允许使用以0x开头的十六进制)

  选项

  -m mode, --mode=mode

  为新建立的文档设定模式,就象应用命令chmod相同,以后仍然使用缺省模式建立新目录。 缺省地,所产生的文档模式为0666(‘a+rw‘)

  GNU 标准选项

  --help

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

  --version

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

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

  mknod /dev/input/mouse0 c 13 32

  也可以

  mknod /tmp/mymouse c 13 32

  /**********************************************************************************************************************/

  下面是某个网友利用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

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

主次设备号

定义  主设备号被系统用来确定驱动程式(设备类型:如USB设备,硬盘设备),次设备号被驱动程式用来确定具体的设备。

查看主、次设备号

  字符设备驱动的特殊文件,可以通过ls-l输出的第一列中的“c”标明。/dev下还有块设备,但它们是“b”来识别;尽管如下介绍的某些内容也适用于块设备,但我们这章只关注字符设备。

  如果你执行ls-l命令,在设备文件条目中的最新修改日期前你会看到二个数(用逗号分隔),这个位置通常显示文件长度。这二个数就是相应设备的主设备号和次设备号。下面的列表给出了我使用的系统上的一些设备。它们的主设备号是10,7,1和4,而次设备号是0,3,5,64,5和129。

  crw-rw-rw- 1 root root 1, 3 Feb23 1999 null

  crw------- 1 root root 10, 1 Feb23 1999 psaux

  crw------- 1 rubini tty 4, 1 Aug16 22:22 tty1

  crw-rw-rw- 1 root dialout 4, 64 Jun30 11:19 ttyS0

  crw-rw-rw- 1 root dialout 4, 65 Aug16 00:00 ttyS1

  crw------- 1 root sys 7, 1 Feb23 1999 vcs1

  crw------- 1 root sys 7, 129 Feb 23 1999 vcsa1

  crw-rw-rw- 1 root root 1, 5 Feb23 1999 zero

  主设备号识别设备对应的驱动程序。例如,/dev/null和/dev/zero都由驱动程序1管理,而所有的虚拟控制台和串口终端都由驱动程序4管理,同样,vcs1和 vcsa1由驱动程序7管理。当设备打开(open)时,内核利用主设备号分派执行相应的驱动程序。

  次设备号只由相应的设备驱动程序使用;内核的其他部分不使用它,仅将它传递给驱动程序。所以一个驱动程序管理若干个设备并不为奇(如上面的例子所示),次序号提供了一种区分它们的方法。 尽管2.4版本的内核引入了一种新的特性(可选):设备文件系统,devfs。如果使用了这种文件系统,那设备文件将变得简单,但也很原来有很大的不同。另一方面,这新的文件系统带来了一些用户可见的不兼容特性。

应用

  当没有使用devfs时,向系统增加一个驱动程序意味着要赋值它一个主设备号。这一赋值过程应该在驱动程序(模块)的初始化过程中完成,它调用如下函数,这个函数定义在<linux/fs.h>:

  int register_chrdev(unsigned intmajor, const char *name, struct file_operations *fops);

  返回值提示成功或者失败。返回一个负值,表示出错;返回零或正值,表示成功。参数major是所请求的主设备号,name是你的设备的名字,它将在/proc/devices中出现,fops是一个指向函数队列的指针,利用它完成对设备函数的调用。

  主设备号是一个用来索引静态字符设备组的整数,“动态分配主设备号”将在本章的稍后部分中介绍怎样选择一个主设备号。2.0内核支持128个设备驱动,而2.2和2.4内核支持256个(保留数值0和255为将来使用)。而次版本号(8位字节的数)并没有传递给register_chrdev函数,因为次版本号是驱动程序自己使用的。开发团队为了增加内核可能支持的设备数量而带来了很大的压力,在开发树2.5版本内核的目标中,设备号至少是16位的。

  一旦设备驱动程序注册到内核表中,它的操作都与分配的主设备号匹配,何时在字符设备文件上操作都与它的主设备号相关联,内核都会通过file_operations结构体查找并调用相应的驱动程序中的函数。为了这个原因,传递给register_chrdev的指针应该是指向驱动程序中的全局结构体,而不是一个局部的一个模块初始化函数。

  接下来的问题就是如何给程序一个名字以被它们用来请求你的设备驱动程序。这个名字必须插入到/dev目录中,并与你的驱动程序的主设备号和次设备号相连。

  在文件系统上创建一个设备节点的命令是mknod,而且你必须是超级用户才能操作。除了要创建的节点名字外,该命令还带三个参数。例如,命令:

  mknod /dev/scull0 c 254 0

  创建一个字符设备(c),主设备号是254,次设备号是0。由于历史原因,次设备号应该在0-255范围内,有时它们存储在一个字节中。存在很多原因扩展可使用的次设备号的范围,但就现在而言,仍然有8位限制。

  请注意:如果一旦用mknod生成了一个特别的设备文件,它就永远存在了硬盘上,除非你明白的删除了它。你可以通过执行命令"rm"命令来删除例子中的设备。

  rm /dev/scull0

动态分配主设备号

  某些主设备号已经静态地指派给了大部分常见设备。在内核源代码树的Documentation/device.txt文件中可以找到这些设备的列表。由于许多编号已经分配了,为新设备选择一个唯一的编号是很困难的——可配置的设备要比主设备号多得多。

  所幸,可以对主设备号进行动态分配。如果调用register_chrdev时将major设为0,则该函数会自动选择一个空闲的号码并返回作为该设备的主设备号。返回的主设备号总是正值,而返回负值时表明出错。注意如下两种情况的细微差别:若调用者请求一个动态的主设备号时函数register_chrdev返回值为所分配的主设备号,而当成功地注册到一个预先定义的主设备号时(即不采用动态分配而采用静态指派方式),函数返回值为0而非主设备号。

  对于private dirvers,强烈建议使用动态分配的方法来得到主设备号。相反,如果你的设备普遍应用在大多数场合甚至要被包含在官方的内核树中,你就需要指派一个主设备号作为专用。

  动态分配的缺点是:由于分配给你的主设备号不能保证总是一样的,因而你无法用mknod命令事先创建设备节点(即设备文件)(可在加载模块时用脚本自动创建)。这意味着你将不能使用Chapter 11中介绍的关于“按需载入模块(loading-on-demandof your driver)”的先进特性。对于用于一般用途的驱动程序,这不是什么问题,因为一旦分配了设备号,你就可以从/proc/devices读取相关的设备号信息。

  为了加载一个用动态分配来得到主设备号的驱动程序,对insmod的调用需要被替换为一个简单的脚本,这个脚本先调用insmod,再读/proc/devices以得到主设备号,并创建设备文件。

实例

  下面这个脚本,scull_load,是scull发行中的一部分。使用以模块形式发行的驱动程序的用户可以从系统的rc.local文件中调用这个脚本,或者在需要模块时手工调用。rc.local可在/etc/rc.d/下找到。(中文版中还提到一种方法:使用kerneld。)

  #!/bin/sh

  module=”scull”

  device =”scull”

  mode =”664”

  #invoke insmod with all

  arguments we were passed

  #and use a pathname, as

  newer modutils don’t look in. by default

  /sbin/insmod –f ./$module.o

  $* || exit

  #remove stale nodes

  rm –f /dev/$(device)[0-3]

  major=’awk “

  [url=file://///$2==/]\\$2==\[/url]

  ”$module\” {print

  [url=file://///$1]\\$1[/url]

  }” /proc/devices’

  mknod /dev/${device}0 c

  $major 0

  mknod /dev/${device}1 c

  $major 1

  mknod /dev/${device}2 c

  $major 2

  mknod /dev/${device}3 c

  $major 3

  #give appropriate group/permissions, and change the group.

  #Not all distributions have staff; some have “wheel” instead.

  group=”staff”

  grep ‘^staff:’ /etc/group

  > /dev/null || group=’wheel’

  chgrp $group

  /dev/${device}[0-3]

  chmod $mode

  /dev/${device}[0-3]

  只要重新定义脚本中的变量并对mknod命令行进行修正该脚本同样可以用于其驱动程序。

  读者可能对最后几行迷惑不解:为什么要改变设备的组(group)和访问权限(mode)呢?原因是该脚本只能由超级用户运行,因而新建的设备文件自然属于root。默认权限位只允许root对其有写访问权限,而其他用户只有读权限。通常设备文件需要不同的访问策略,比如只对某一组用户开放访问权限,因而需要改变某些情况下的访问权限。

时间: 2024-10-11 14:33:26

mknod用法以及主次设备号【转】的相关文章

14.文件系统——软RAID的实现(一)(mdadm,RAID0,主次设备号)

前文中介绍过,软RAID其实是通过md来实现的,它本质上是一个程序,用来模拟RAID.它依赖于CPU完成,需要占用大量的CPU时钟周期,所以性能不会太好:并且它完全依赖于当前操作系统,所以一旦操作系统损坏,则很有可能影响到该RAID的使用,因此在生产环境中,不建议使用软RAID.这里仅对软RAID的实现方式作一些简单的介绍. md模块可以基于任何块设备来创建,也就意味着它可以使用一个完整的分区来创建,例如使用/dev/sdb5和/dev/sdb6来实现RAID1:它可以在/dev/md0和/de

主次设备号 Device Major and Minor Numbers

对于一个设备文件而言真正重要的标志是它的主次设备号(major and minor device numbers).如果我们用ls命令列出/dev下的一个设备: [email protected]:~$ ls -l /dev/console crw------- 1 root root 5, 1 Nov 28 11:56 /dev/console 可以看到,这是一个字符设备,但是在普通文件显示大小的地方用"5,1"代替了.其中5就是这个设备文件的major number,而1就是它的m

设备与驱动的关系以及设备号、设备文件

Linux设备分类Linux下的设备通常分为三类,字符设备,块设备和网络设备. 字符设备 一个字符设备是一种字节流设备,对设备的存取只能按顺序按字节的存取而不能随机访问,字符设备没有请求缓冲区,所有的访问请求都是按顺序执行的.Linux下的大多设备都是字符设备.应用程序是通过字符设备节点来访问字符设备的.设备节点一般都由mknod命令都创建在/dev目录下,下面的例子显示了串口设备的设备节点.字符设备文件的第一个标志是前面的“c”标志. root#ls -l /dev/ttyS[0-3]crw-

内核怎么通过主设备号找驱动、次设备号找设备

之前看韦东山老师视频,说到linux驱动就知道主设备号找驱动,次设备号找设备.这句到底怎么理解呢,如何在驱动中实现呢,在介绍该实现之前先看下内核中主次设备号的管理.在内核中,dev_t  类型( 在 <linux/types.h>头文件有定义 ) 用来表示设备号,包括主设备号和次设备号两部分.对于 2.6.x内核,dev_t是个32位量,其中高12位用来表示主设备号,低20位用来表示次设备号. <span style="font-family:Times New Roman;f

指定子设备号创建字符设备

目录 指定子设备号字符设备 流程 实例程序 测试 title: 指定子设备号创建字符设备 tags: linux date: 2018/12/28 19:57:24 toc: true --- 指定子设备号字符设备 流程 内核中设备号分为主设备号和次设备号,以前注册字符设备驱动的时候,直接占用了主设备号包含了255个子设备号,也就是内核最多支持255个设备驱动(如果主设备号占据8位) 在Linux2.6中内核可以指定主设备号和对应的子设备号给一个fileoperation,如下图所示 流程如下:

设备号

一. <include/linux/fs.h > int register_chrdev_region(dev_t from, unsigned count, const char *name); 函数用于已知起始设备的设备号的情况 :要先查看cat /proc/devices去查看没有使用的 from:要分配的设备编号范围的初始值, 这组连续设备号的起始设备号, 相当于register_chrdev()中主设备号Count:连续编号范围.   是这组设备号的大小(也是次设备号的个数)Name

linux设备号详解

原文:http://blog.csdn.net/zjjyliuweijie/article/details/7001383 linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取).块设备(有缓冲且可以随机存取).每个字符设备和块设备都必须有主.次设备号,主设备号相同的设 备是同类设备(使用同一个驱动程序).这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的物理硬件,又称为"虚拟设备").每个设备在 /dev 目录下都有一个对应的

Linux中设备号及设备文件【转】

本文转载自:http://blog.csdn.net/ymangu666/article/details/39292651 主.次设备号 应用程序可以通过对/dev 目录下的设备文件读写,从而访问实际的设备.1)每个设备文件对应有两个设备号:主设备号,次设备号① 主设备号:标识该设备的类型,也表示了该设备所使用的驱动程序:  驱动程序在初始化时,会注册它的驱动及对应主设备号到系统中,可以通过/proc/devices 文件来驱动系统设备的主设备号.② 次设备号:表示使用同一设备驱动程序的不同硬件

linux驱动之设备号与创建设备节点

设备号: 1.自己主动分配 major = register_chrdev(0,"first_drv",&first_sdv_fops);//注冊 注冊设备时给设备号写0,则内核会自己主动分配一个主设备号返回. 2.手动指定 到 proc/devices 文件下查找都有哪些主设备号.假设没有被使用的我们就可以拿过来使用它. 应用程序设备节点: 我们会使用open这个函数带开一个设备,那么open("dev/xxx")中dev/xxx 这个设备节点怎么来? 1