Linux的设备办理是和文件体系紧密结合的,各种设备都以文件的办法存放在/dev目录下,称为设备文件。应用程序能够翻开、封闭和读写这些设备文件,完结对设备的操作,就像操作一般的数据文件相同。为了办理这些设备,体系为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区别不同品种的设备,而次设备号用来区别同一类型的多个设备。关于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。
一个字符设备或许块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表明一个特定的驱动程序。次设备号用来表明运用该驱动程序的各设备。例如一个嵌入式体系,有两个LED指示灯,LED灯需求独立的翻开或许封闭。那么,能够写一个LED灯的字符设备驱动程序,能够将其主设备号注册成5号设备,次设备号别离为1和2。这儿,次设备号就别离表明两个LED灯。
设备文件一般都在 /dev 目录下。如:
如上,前面榜首个字符为c 的表明字符设备。在字符设备里,有主设备号和次设备号。如上1,4,7 别离是主设备号,0,1,3,7,70,71都是次设备号。一般的,主设备号标识出与设备相关的设备驱动。如 /dev/null 和 /dev/full 由 1 号驱动来办理,/dev/vcs 和/dev/vcs1由 7 号驱动来办理,/dev/ttyS6 由 4 号驱动来办理。
现在的 Linux 内核答应多个驱动同享一个主设备号,但更多的设备都遵从一个驱动对一个主设备号的准则。
内核由次设备号确认当时所指向的是哪个设备。依据所编写的驱动程序,能够从内核那里得到一个直接指向设备的指针,或许运用次设备号作为一个设备本地数组的索引。但不论如何,内核本身简直不知道次设备号的什么事情。
设备号的内部表明在内核中,dev_t 类型( 在 linux/types.h 头文件有界说 ) 用来表明设备号,包含主设备号和次设备号两部分。关于 2.6.x 内核,dev_t 是个 32 位量,其间 12 位用来表明主设备号,20 位用来表明次设备号。
在 linux/types.h 头文件里界说有
主设备号和次设备号的获取
为了写出可移植的驱动程序,不能假定主设备号和次设备号的位数。不同的机型中,主设备号和次设备号的位数可能是不同的。应该运用MAJOR宏得到主设备号,运用MINOR宏来得到次设备号。下面是两个宏的界说:(linux/kdev_t.h)
#define MINORBITS 20 /*次设备号*/
#define MINORMASK ((1U << MINORBITS) – 1) /*次设备号掩码*/
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) /*dev右移20位得到主设备号*/
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) /*与次设备掩码与,得到次设备号*/
MAJOR宏将dev_t向右移动20位,得到主设备号;MINOR宏将dev_t的高12位清零,得到次设备号。相反,能够将主设备号和次设备号转换为设备号类型(dev_t),运用宏MKDEV能够完结这个功用。
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
MKDEV宏将主设备号(ma)左移20位,然后与次设备号(mi)相与,得到设备号
静态分配设备号
静态分配设备号,便是驱动程序开发者,静态地指定一个设备号。关于一部分常用的设备,内核开发者现已为其分配了设备号。这些设备号能够在内核源码documentation/ devices.txt文件中找到。假如只要开发者自己运用这些设备驱动程序,那么其能够挑选一个没有运用的设备号。在不增加新硬件的时分,这种办法不会发生设备号抵触。可是当增加新硬件时,则很可能形成设备号抵触,影响设备的运用。
动态分配设备号
因为静态分配设备号存在抵触的问题,所以内核社区主张开发者运用动态分配设备号的办法。动态分配设备号的函数是alloc_chrdev_region()。