参考:http://blog.chinaunix.net/uid-24460251-id-2606762.html
http://blog.csdn.net/zjjyliuweijie/article/details/7001383

现有linux内核支持的设备号,可通过/Documentation/devices.txt查看,linux内核所能识别的所有设备都记录在http://www.lanana.org/docs/device-list/。
给设备分配设备号时尽量避开系统已使用的主次设备号。

分配并注册主次设备号
设备号是在驱动module中分配并注册的,也就是说,驱动module拥有这个设备号(我的理解),而/dev目录下的设备文件是根据这个设备号创建的。因此,当访问/dev目录下的设备文件时,驱动module就知道,自己该出场服务了(当然是由内核通知)。设备即文件,两者通过设备号连接。
在Linux内核看来,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务;而次设备号则用来标识具体且唯一的某个设备。
在内核中,用dev_t类型(其实就是一个32位的无符号整数)的变量来保存设备的主次设备号,其中高12位表示主设备号,低20位表示次设备号。
设备获得主次设备号有两种方式:一种是手动给定一个32位数,并将它与设备联系起来(即用某个函数注册);另一种是调用系统函数给设备动态分配一个主次设备号。
对于手动给定一个主次设备号,使用以下函数:
int register_chrdev_region(dev_t from, unsigned count, const char *name);
其中from是我们手动给定的设备号,count是所请求的连续设备号的个数,而name是和该设备号范围关联的设备名称,它将出现在/proc/devices和sysfs中。
比如,若from为0x3FFFF0,count为0x5,那么该函数就会为5个设备注册设备号,分别是0x3FFFF0、 0x3FFFF1、 0x3FFFF2、 0x3FFFF3、 0x3FFFF4,其中0x3(高12位)为这5个设备所共有的主设备号(也就是说这5个设备都使用同一个驱动程序)。而0xFFFF0、 0xFFFF1、 0xFFFF2、 0xFFFF3、 0xFFFF4就分别是这5个设备的次设备号了。需要注意的是,若count的值太大了,那么所请求的设备号范围可能会和下一个主设备号重叠。比如若 from还是为0x3FFFF0,而count为0x11,那么from+count=0x400001,也就是说为最后两个设备分配的主设备号已经不是0x3,而是0x4了!用这种方法注册设备号有一个缺点,那就是若该驱动module被其他人广泛使用,那么无法保证注册的设备号是其他人的 Linux系统中未分配使用的设备号。(这是原文档中内容,实际是主设备号一般由系统给出,此设备号从0开始)
对于动态分配设备号,使用以下函数:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
该函数需要传递给它指定的第一个次设备号baseminor(一般为0)和要分配的设备数count,以及设备名,调用该函数后自动分配得到的设备号保存在dev中。动态分配设备号可以避免手动指定设备号时带来的缺点,但是它却也有自己的缺点,那就是无法预先在/dev下创建设备节点,因为动态分配设备号不能保证在每次加载驱动module时始终一致(其实若在两次加载同一个驱动module之间并没有加载其他的module,那么自动分配的设备号还是一致的,因为内核分配设备号并不是随机的,但是书上说某些内核开发人员预示不久的将来会用随机方式进行处理),不过,这个缺点可以避免,因为在加载驱动module后,我们可以读取/proc/devices文件以获得Linux内核分配给该设备的主设备号。
与主次设备号相关的3个宏:
MAJOR(dev_t dev):根据设备号dev获得主设备号;
MINOR(dev_t dev):根据设备号dev获得次设备号;
MKDEV(int major, int minor):根据主设备号major和次设备号minor构建设备号。

另解:
Linux的设备管理是和文件系统紧密结合的,把设备和文件关联起来,这样系统调用可以直接用操作文件一样的方法来操作设备。各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。

设备号扩展:
Linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取)、块设备(有缓冲且可以随机存取)。每个字符设备和块设备都必须有主、次设备号,主设备号相同的设备是同类设备(使用同一个驱动程序)。这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的物理硬件,又称为"虚拟设备")。每个设备在 /dev 目录下都有一个对应的文件(节点)。可以通过 cat /proc/devices 命令查看当前已经加载的设备驱动程序的主设备号。内核能够识别的所有设备都记录在原码树下的 documentation/devices.txt 文件中。在 /dev 目录下除了字符设备和块设备节点之外还通常还会存在:fifo管道、socket、软/硬连接、目录。这些东西没有主/次设备号。
$ 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)。
linux内核所能识别的所有 设备都记录在http://www.lanana.org/docs/device-list/,而内核原码树中的 documentation/devices.txt 可能不是最新版本。

linux设备号分配的更多相关文章

  1. linux中的设备名称和设备号

    看赵炯博士的<linux 0.11 源代码注释>已经两三周了,从今天起开始将一些个人总结和感悟分小标题写出来,聊作记忆以供后来查看.在linux0.11源码的 /linux/boot/bo ...

  2. Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...

  3. linux主次设备号介绍

    1.主设备号与次设备号的功能 在Linux内核中,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务:而次设备号则用来标识具体且唯一的某个设 ...

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

    本文转载自:http://blog.csdn.net/ymangu666/article/details/39292651 主.次设备号 应用程序可以通过对/dev 目录下的设备文件读写,从而访问实际 ...

  5. linux主次设备号【转载】

    一个字符设备或者块设备都有一个主设备号和次设备号.主设备号和次设备号统称为设 备号.主设备号用来表示一个特定的驱动程序.次设备号用来表示使用该驱动程序的各 设备.例如一个嵌入式系统,有两个LED指示灯 ...

  6. ⭐linux主次设备号介绍

    1.主设备号与次设备号的功能 在Linux内核中,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务:而次设备号则用来标识具体且唯一的某个设 ...

  7. Linux设备驱动程序 之 主次设备号

    主设备号和次设备号 对字符设备的访问是通过文件系统内的设备名称进行的,这些名称被称为特殊文件.设备文件.或者简单称之为文件系统树的节点,它们通常位于/dev目录.字符设备驱动程序的设备文件可以通过ls ...

  8. Linux:主设备号和次设备号

    http://www.linuxidc.com/Linux/2011-03/33863.htm     Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备 ...

  9. linux驱动设备号

    一.设备号基础 一般来说,使用ls -l命令在时间一列的前一列的数字表示的是文件大小,但如果该文件表示的是一个设备的话,那时间一列的前一列将有两个数字,用逗号分隔开,如下图: 前一个数字表示主设备号, ...

随机推荐

  1. C语言实现括号配对问题

    代码如下: #include<stdio.h> #include<string.h> #include<stdlib.h> // 写一个判断的括号是否匹配的函数 i ...

  2. 阿里p6面试

    电话面试: 第一次面试关注的问题,1)java基础: jvm 内存回收,垃圾回收基本原理,Java并发包的线程池,Java8的新特性.nio 堆排序.conrenthashmap , concurre ...

  3. pdf.js 添加自定义loading动画

    最近做了个手机端pdf预览的功能,用到pdf.js这个库,效果还不错.但是在网络差.文件大时,页面一直空白,体验不是很好. 于是加了个loading动画. <div id="loadi ...

  4. fl2440字符设备led驱动

    首先要明白字符设备驱动注册的基本流程 当我们调用insomd命令加载驱动后,驱动程序从module_init函数开始执行:硬件初始化 -> 申请主次设备号 -> 定义fops(file_o ...

  5. Hadoop之Sqoop详解

    sqoop数据迁移1.简介 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具. 导入数据:MySQL,Oracle导入数据到Hadoop的HDFS.HIVE.HBA ...

  6. 数据挖掘算法之聚类分析(二)canopy算法

    canopy是聚类算法的一种实现 它是一种快速,简单,但是不太准确的聚类算法 canopy通过两个人为确定的阈值t1,t2来对数据进行计算,可以达到将一堆混乱的数据分类成有一定规则的n个数据堆 由于c ...

  7. SVN服务的部署及使用

      环境说明 系统版本     CentOS 7.2 x86_64   SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是 ...

  8. MPTCP 源码分析(四) 发送和接收数据

    简述:      MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条 路径来发送数据.MPTCP在接收数据方面与TCP的区别是子路径对无序包 进行重排后,MPTCP的mpcb需要多所有子 ...

  9. HTTP——代理协议 HTTP/1.1的CONNECT方法

    我们平时使用HTTP协议无非就是GET.POST这些方法,但是HTTP的内容远不止那些.今天就来说说HTTP代理使用的CONNECT.这个不是在网页开发上用的,如果没兴趣就跳过吧. APACHE只是作 ...

  10. PgSql备份pg_dump与还原手记pg_restore(转)可以直接跳转至最后面的示例进行查看

    PgSql备份pg_dump与还原手记pg_restore(转) 可以直接跳转至最后面的示例进行查看 真没有想到,以前一直是PostgreSQL使用者,突然需要库移植又成了头一招了!原来它与mysql ...