当前位置: 首页 > news >正文

Linux字符设备驱动模型之设备号

从上文中可知,在Linux用户空间中,如若需要操作硬件设备,均通过/dev目录下的设备文件节点进行操作,基本上每一种设备都会存在一个或者多个的设备节点。

并且在Linux内核中,其表示字符设备的结构成员也提供了相应的设备号。

设备号成员为dev_t dev;那么其与设备之间的关系是什么呢?它又与用户空间的操作是和关系??

一、设备号

那么设备文件节点又是如何与Linux内核驱动程序进行对应的映射关系呢???答案是:主设备号。

在前文举例过,可能会存在多个相同的设备运行在Linux系统中,这些设备所使用的是同一个内核驱动程序,那么是如何区分各个设备的呢???答案是:次设备号。

那么设备号在用户空间中,是如何体现的呢???

在我们现有的Linux系统中,进行/dev目录下,执行命令。

命令:ls -l

如上图所示,在其设备节点文件的属性中,可以查看到设备节点的主设备号和次设备号。其中逗号‘,’前为主设备号,后为次设备号。并且如上图所示,对于loop设备而言,其有很多相同的设备运行在Linux操作系统中,那么他们的各个相同的设备都具有唯一的节点名称,但他们的主设备号相同,均为7;次设备号不同,按照节点的顺序进行排列。

二、设备号操作

在Linux内核源码中,使用结构体dev_t类型来定义设备号。实际上dev_t类型为32位的unsigned int类型(在Linux内核源码中可以进行跟踪)。其中高12位作为存储主设备号,低20位作为存储次设备号。

那么就存在了如下几个问题:

1.如果知道主设备号和次设备号,那么怎么组合成dev_t类型的数据?

在Linux内核中,提供了MKDEV方法宏来进行组合主设备号和次设备号。其原型如下:

用法为:dev_t dev = MKDEV(主设备号,次设备号)

2.如何从dev_t类型的数据中解析出主设备号?

如上图,在Linux内核中采用了MAJOR方法宏来进行解析主设备号。用法如下:

主设备号 = MAJOR(dev_t dev)

3.如何从dev_t类型的数据中解析出次设备号?

如上图,在Linux内核中采用了MINOR方法宏来进行解析主设备号。用法如下:

次设备号 = MINOR(dev_t dev)

三、设备号分配/申请

因为是在Linux内核框架下进行编写设备驱动程序,那么每一个设备的设备号可以有Linux内核提供的方法来进行分配。

Linux内核中如何为设备分配一个主设备号???

实际上在Linux内核中提供了两种方法可以进行分配主设备号。分别为静态申请设备号和动态分配设备号。

静态申请设备号:程序员自己选择一个数字作为某一个设备的主设备号,再确定其次设备号(实际上如果是单一的设备,通常次设备号为0),通过组合得到设备号,然后通过函数register_chrdev_region向内核申请主设备号使用。其原型如下:

静态申请设备号的缺点在于,如果所申请的设备号已经在内核中被其他设备驱动使用了,则会申请失败。并且另一点是,在Linux内核中存在一些设备驱动的设备号为固定的设备号,例如:串口UART、I2C设备驱动等。

动态分配设备号:Linux内核提供方法函数alloc_chrdev_region,由内核动态的分配一个可用的主设备号给相应的设备驱动。其原型为:

动态分配设备号的优点在于,因为Linux内核本身自己知道了哪些设备号已经被使用了,所以基本不会导致分配到已用了的设备号,从而不会申请设备号失败。

四、设备号注销

实际上无论是使用动态分配得到的设备号,还是使用静态申请得到的设备号,当Linux系统中不再需要相应的硬件设备时,可将其设备驱动进行注销,那么重要的一步就是在设备驱动退出时,使用方法函数unregister_chrdev_region函数释放相应的设备号。其原型为:

设备号释放后,设备节点文件将不存在。

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!(点击找小助理领取)

http://www.lryc.cn/news/24294.html

相关文章:

  • C++多态原理
  • PMP认证与NPDP认证哪个含金量高?
  • 改进YOLOv7-Tiny系列:首发改进结合BiFPN结构的特征融合网络,网络融合更多有效特征,高效涨点
  • PPC Insights系列:洞见安全多方图联邦
  • SQLite注入记录(目前最全、核心函数用法、布尔盲注、时间盲注、webshell、动态库,绕过方式)
  • Java简单的生成/解析二维码(zxing qrcode)
  • 若依项目导出后端响应的Excel文件流处理
  • 华为OD机试【独家】提供C语言题解 - 数组排序
  • JVM详解——内存结构
  • Jvisualvm监控Tomcat以及相关参数优化
  • 界面组件DevExpress WinForms v22.2 - 全面升级数据展示功能
  • 正点原子第一期
  • 「mysql是怎样运行的」第24章 一条记录的多幅面孔---事务的隔离级别与MVCC
  • 入门Java第十五天 线程
  • 探索用卷积神经网络实现MNIST数据集分类
  • MySQL 索引失效场景
  • Xcode开发工具,图片放入ios工程
  • 操作系统权限提升(十九)之Linux提权-SUID提权
  • 直播 | StarRocks 实战系列第三期--StarRocks 运维的那些事
  • KingabseES执行计划-分区剪枝(partition pruning)
  • Operator-sdk 在 KaiwuDB 容器云中的使用
  • 【数据挖掘】2、数据预处理
  • (四十六)大白话在数据库里,哪些操作会导致在表级别加锁呢?
  • 【Android源码面试宝典】MMKV从使用到原理分析(二)
  • 如何使用ADFSRelay分析和研究针对ADFS的NTLM中继攻击
  • 【Python学习笔记】第二十二节 Python XML 解析
  • 5分钟轻松拿下Java枚举
  • 华为OD机试【独家】提供C语言题解 - 最小传递延迟
  • 【Web前端】关于JS数组方法的一些理解
  • 多智能体集群协同控制笔记(1):线性无领航多智能体系统的一致性