Linux驱动设备号

什么是设备号

 linux中设备号是用来标记一类设备以及区分这类设备中具体个体的一组号码,由主设备号和次设备号组成,主设备号用来标记设备的类型,次设备号用来区分在这类设备中具体的个体设备。

主设备号:用来标识与设备文件相关的驱动程序,        ——反应设备类型

次设备号:为内核所用,被驱动程序用来辨别操作那个设备文件    ——区分同类型的具体某个设备

1、设备号的组成

Linux 中每个设备都有一个设备号,设备号由主设备号和次设备号两部分 组成,主设备号表示某一个具体的驱动,次设备号表示使用这个驱动的各个设备。Linux 提供了 一个名为 dev_t 的数据类型表示设备号,dev_t 定义在文件 include/linux/types.h 里面,定义如下:

12 typedef __u32 __kernel_dev_t;

......

15 typedef __kernel_dev_t dev_t;

可以看出 dev_t 是__u32 类型的,而__u32 定义在文件 include/uapi/asm-generic/int-ll64.h 里 面,定义如下:

26  typedef unsigned int __u32;

dev_t 其实就是 unsigned int 类型,是一个 32 位的数据类型。这 32 位的数据构成了主设备号和次设备号两部分,其中高 12 位为主设备号,低 20 位为次设备号。因此 Linux 系统中主设备号范围为 0~4095,所以大家在选择主设备号的时候一定不要超过这个范围。在文 件 include/linux/kdev_t.h 中提供了几个关于设备号的操作函数(本质是宏)。

#define MINORBITS   20

#define MINORMASK   ((1U << MINORBITS) - 1)

#define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))

#define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))

#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))

宏 MINORBITS 表示次设备号位数,一共是 20 位。

宏 MINORMASK 表示次设备号掩码。

宏 MAJOR 用于从 dev_t 中获取主设备号,将 dev_t 右移 20 位即可。

宏 MINOR 用于从 dev_t 中获取次设备号,取 dev_t 的低 20 位的值即可。

宏 MKDEV 用于将给定的主设备号和次设备号的值组合成 dev_t 类型的设备号。

2、设备号的分配

1、静态分配设备号

注 册字符设备的时候需要给设备指定一个设备号,这个设备号可以是驱动开发者静态的指定一个 设备号,比如选择 200 这个主设备号。有一些常用的设备号已经被 Linux 内核开发者给分配掉 了,使用“cat /proc/devices”命令即可查看当前系统中所有已经使用了的设备号。

2、动态分配设备号

静态分配设备号需要我们检查当前系统中所有被使用了的设备号,然后挑选一个没有使用 的。而且静态分配设备号很容易带来冲突问题,Linux 社区推荐使用动态分配设备号,在注册字 符设备之前先申请一个设备号,系统会自动给你一个没有被使用的设备号,这样就避免了冲突。

卸载驱动的时候释放掉这个设备号即可,设备号的申请函数如下:

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char*name)

函数 alloc_chrdev_region 用于申请设备号,此函数有 4 个参数:

dev:保存申请到的设备号。

baseminor:次设备号起始地址,alloc_chrdev_region 可以申请一段连续的多个设备号,这 些设备号的主设备号一样,但是次设备号不同,次设备号以 baseminor 为起始地址地址开始递 增。一般 baseminor 为 0,也就是说次设备号从 0 开始。

count:要申请的设备号数量。

name:设备名字。

注销字符设备之后要释放掉设备号,设备号释放函数如下:

void unregister_chrdev_region(dev_t from, unsigned count)

此函数有两个参数:

from:要释放的设备号。

count:表示从 from 开始,要释放的设备号数量

你可能感兴趣的:(linux)