扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

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

23小时前
157
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

一、Linux内核字符设备号

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

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

主设备号:关联到具体的驱动程序(如 1 对应 mem5 对应 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.h

7#define MINORBITS   20
8#define MINORMASK   ((1U << MINORBITS) - 1)
9
10#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内核字符设备号管理规则:

    数组**chrdevs[CHRDEV_MAJOR_HASH_SIZE]**维护所有的字符设备主次设备号;
    主设备号值区间[0 512],数组下标与主设备号值关系:小于255的主设备号值等于下标,大于254小于512的主设备号对255取余后的值等于小标(比如主设备号251和506共用同一个下标);
    每一个主设备号(251和506虽然公用同一个数组下标,但是各自对应2^20个次设备号)对应的次设备号区间[0-1048575];
    次设备号可以分块申请,块内次设备号必须连续,各个块之间的次设备号不能重叠,每一块次设备号由结构体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 */
    申请字符设备:chardev1,主设备号:251,次设备号基值:0、个数3、区间:[0-2];
    申请字符设备:chardev2,主设备号:251,次设备号基值:3、个数4、区间:[3-6];
    申请字符设备:chardev3,主设备号:506,次设备号基值:0、个数3、区间:[0-2];
    申请字符设备:chardev4,主设备号:506,次设备号基值:3、个数4、区间:[3-6];
    申请字符设备:chardevA,主设备号:234,次设备号区间:[0-255];
    申请字符设备:chardevB,主设备号:489,次设备号区间:[0-255];

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

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

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

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

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

五、代码获取

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

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

公众号『一口Linux』号主彭老师,拥有15年嵌入式开发经验和培训经验。曾任职ZTE,某研究所,华清远见教学总监。拥有多篇网络协议相关专利和软件著作。精通计算机网络、Linux系统编程、ARM、Linux驱动、龙芯、物联网。原创内容基本从实际项目出发,保持原理+实践风格,适合Linux驱动新手入门和技术进阶。