【内核驱动基础】主设备号与次设备号

目录

一、主次设备号的定义

二、设备号常用宏

三、设备号的分配与释放

[3.1 动态分配与释放](#3.1 动态分配与释放)

[3.2 静态分配与释放](#3.2 静态分配与释放)

参考资料


一、主次设备号的定义

在 Linux 里,/dev/xxx 这种设备文件本质上是一个 特殊文件(inode) ,里面最关键的"身份信息"就是一个 设备号 dev_t(本质上是一个整型编码,是一个32位的数据类型,高12位为主设备号,低20位为次设备号)

  • 主设备号(major):告诉内核"应该找哪个驱动/哪个字符设备类(或者块设备类)来处理这个打开请求"
  • 次设备号(minor):告诉驱动"同一个驱动下的哪一个具体实例/通道/端口/逻辑设备"

该类型的定义是在include/linux/types.h文件中:

当用户态做:

复制代码
fd = open("/dev/xxx", O_RDWR);

VFS 在解析到这是字符设备/块设备文件后,会拿到这个 inode 里保存的 dev_t,拆出 major/minor,然后去内核里找到对应的 cdev(字符设备)或 bdev(块设备) ,把这次 open 转交给对应的 file_operations

在自己的设备中,我们可以输入:

复制代码
ls -l /dev/xxx0

来查看设备节点的主次设备号与设备类型

使用下述指令,可以查看系统当前注册的主设备号:

复制代码
cat /proc/devices

二、设备号常用宏

在include/linux/kdev_t.h包含了一些设备号相关的常见宏:

  • MAJOR(dev_t) / MINOR(dev_t):拆出主/次设备号
  • MKDEV(major, minor):把主/次设备号合成一个 dev_t

三、设备号的分配与释放

设备号分配的本质是:向内核申请一个 设备号区间(一个 major + 若干连续 minor),并在退出时把这段区间归还。

设备号分配与释放的函数在头文件include/linux/fs.h这里声明了:

  • alloc_chrdev_region()

  • register_chrdev_region()

  • unregister_chrdev_region()

    并且注释里直接标明来源:/* fs/char_dev.c */,还定义了动态 major 的范围常量(CHRDEV_MAJOR_*)。

3.1 动态分配与释放

动态分配:alloc_chrdev_region() / 释放:unregister_chrdev_region() ,函数原型如下(声明位置:include/linux/fs.h

复制代码
int alloc_chrdev_region(dev_t *dev, unsigned baseminor,
                        unsigned count, const char *name);

void unregister_chrdev_region(dev_t from, unsigned count);

实现位置(代码:fs/char_dev.c

  • alloc_chrdev_region() 传入 major==0 的语义,要求内核在"动态主设备号范围"内找一个未占用 major ,并把 baseminor..baseminor+count-1 这段 minor 区间登记进去;成功后通过 dev 返回起始 dev_t(即 major:baseminor)。
  • unregister_chrdev_region() 反向把这段区间从内部表里摘掉并释放(若跨 major,会按段循环处理)。

3.2 静态分配与释放

静态分配:register_chrdev_region() / 释放:unregister_chrdev_region()

函数原型(声明位置:include/linux/fs.h

复制代码
int register_chrdev_region(dev_t from,unsigned count,constchar *name);

void unregister_chrdev_region(dev_t from,unsigned count);

实现位置(代码:fs/char_dev.c

  • register_chrdev_region() 由调用者给出 from = MKDEV(major, first_minor),内核只做两件关键事:
    1. 检查该 major/minor 区间是否与已登记区间重叠(冲突则失败);
    2. 将这段区间登记为已占用(必要时同样按 major 分段处理)。
  • 释放仍统一使用 unregister_chrdev_region()(同上,按段撤销登记)。

参考资料

相关推荐
猫头虎1 分钟前
【Trea】Trea国内版|国际版|海外版下载|Mac版|Windows版|Linux下载配置教程
linux·人工智能·windows·macos·aigc·ai编程·agi
流浪0019 分钟前
告别静态打印:Linux C 实现实时刷新进度条
linux·运维·c语言
小此方12 分钟前
Re:Linux系统篇(二十)进程篇·五:深入理解 Linux 进程优先级:从底层逻辑到实战修改
linux·运维·服务器
路溪非溪12 分钟前
Linux下物理总线驱动模型之SDIO驱动框架
linux·驱动开发
深圳市九鼎创展科技13 分钟前
九鼎创展 X7110 开发板(JH7110):国产 RISC-V 多媒体平台全解析
大数据·linux·人工智能·嵌入式硬件·ubuntu·risc-v
流浪00116 分钟前
Linux篇(八) Make 与 Makefile 超详细入门教程|从零基础到手写自动化编译
linux·运维·自动化
爱莉希雅&&&21 分钟前
Redis哨兵模式和主从复制和集群模式搭建与扩容缩容
linux·redis·缓存·集群·哨兵·数据库同步
j_xxx404_21 分钟前
Linux线程:从内存分页机制(Page Table/TLB/Page Fault)彻底读懂 Linux 线程本质
linux·运维·服务器·开发语言·c++·人工智能·ai
不做无法实现的梦~24 分钟前
怎么实现codex控制嘉立创EDA绘制原理图
linux
青梅橘子皮28 分钟前
Linux---冯诺伊曼体系结构,操作系统概况
java·linux·运维