当前位置:首页>Linux>Linux驱动|你确定你真的搞懂字符设备号的管理?

Linux驱动|你确定你真的搞懂字符设备号的管理?

  • 2026-10-10 22:10:57
Linux驱动|你确定你真的搞懂字符设备号的管理?

击左上方蓝色“一口Linux”,选择“设为星标”

第一时间看干货文章
☞【干货】嵌入式驱动工程师学习路线
☞【干货】Linux嵌入式知识点-思维导图-免费获取
☞【就业】一个可以写到简历的基于Linux物联网综合项目
☞【就业】简历模版

一、Linux内核字符设备号

每一个字符设备都需要设备号,Linux内核通过字符设备号来区分设备的唯一标识。

设备号:由 主设备号(major) + 次设备号(minor) 组成。

  • 主设备号:关联到具体的驱动程序(如 1 对应 mem,5 对应 tty)。
  • 次设备号:区分同一驱动管理的多个设备。

操作依赖设备号,以下是常用的设备号操作函数(配套使用):

函数
功能
原型
MKDEV(major, minor)
由主 / 次设备号生成 dev_t
dev_t MKDEV(unsigned int major, unsigned int minor);
MAJOR(dev)
从 dev_t 提取主设备号
unsigned int MAJOR(dev_t dev);
MINOR(dev)
从 dev_t 提取次设备号
unsigned int MINOR(dev_t dev);

宏定义位于内核文件

@include/linux/kdev_t.h7#define MINORBITS   208#define MINORMASK   ((1U << MINORBITS) - 1)910#define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))11#define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))12#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))

主次设备号内存组成如下:

Linux内核提供的主要注册字符设备函数:register_chrdev()、register_chrdev_region()。

二、 Linux内核字符设备号管理规则

Linux内核字符设备号管理规则:

  1. 数组**chrdevs[CHRDEV_MAJOR_HASH_SIZE]**维护所有的字符设备主次设备号;
  2. 主设备号值区间[0 512],数组下标与主设备号值关系:小于255的主设备号值等于下标,大于254小于512的主设备号对255取余后的值等于小标(比如主设备号251和506共用同一个下标);
  3. 每一个主设备号(251和506虽然公用同一个数组下标,但是各自对应2^20个次设备号)对应的次设备号区间[0-1048575];
  4. 次设备号可以分块申请,块内次设备号必须连续,各个块之间的次设备号不能重叠,每一块次设备号由结构体struct char_device_struct表示,按照次设备号从小到大顺序,通过链表将各个次设备号块连接起来;

三、实例代码验证

为方便验证代码,彭老师从内核中将字符设备号申请注册的核心代码单独拎出来,去掉一些内核特定函数,

这样我们可以脱离内核进行测试:

四、测试

我们通过一组实例讲解字符设备号的分配:

 register_chrdev_region(MKDEV(251,0),3,"cdev1");  /* 1 */ register_chrdev_region(MKDEV(251,3),4,"cdev2");  /* 2 */ register_chrdev_region(MKDEV(506,0),3,"cdev3");  /* 3 */ register_chrdev_region(MKDEV(506,3),4,"cdev4");  /* 4 */ register_chrdev(234,"cdevA");  /* 5 */ register_chrdev(489,"cdevB");  /* 6 */
  1. 申请字符设备:chardev1,主设备号:251,次设备号基值:0、个数3、区间:[0-2];
  2. 申请字符设备:chardev2,主设备号:251,次设备号基值:3、个数4、区间:[3-6];
  3. 申请字符设备:chardev3,主设备号:506,次设备号基值:0、个数3、区间:[0-2];
  4. 申请字符设备:chardev4,主设备号:506,次设备号基值:3、个数4、区间:[3-6];
  5. 申请字符设备:chardevA,主设备号:234,次设备号区间:[0-255];
  6. 申请字符设备:chardevB,主设备号:489,次设备号区间:[0-255];

申请成功之后,节点信息如下:

如果此时我们要再申请字符设备cdev5:

 register_chrdev_region(MKDEV(506,4),4,"cdev5");

主设备号:506,次设备号基值:4、个数4、区间:[4-7],

那么就会和字符设备cdev4冲突,从而申请失败。

五、代码获取

完整代码获取,关注添加好友,或者后台回复:charno

end

一口Linux 

关注,回复【1024】海量Linux资料赠送

精彩文章合集

文章推荐

☞【专辑】ARM
☞【专辑】粉丝问答
☞【专辑】所有原创
☞【专辑】linux入门
☞【专辑】计算机网络
☞【专辑】Linux驱动
☞【干货】嵌入式驱动工程师学习路线
☞【干货】Linux嵌入式所有知识点-思维导图

最新文章

随机文章