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

Linux驱动开发MODULE_DEVICE_TABLE的作用

作用

MODULE_DEVICE_TABLE宏是用于驱动模块方式开发时会用到的,它的工作原理就是定义驱动的设备ID匹配表,也可以理解为将驱动ID插入到内核匹配表中,它实现的方法就是为当前驱动的设备ID定义一个别名然后insmod命令在加载驱动时会读取这个别名并遍历DTS的compatible是否存在这个设备如果存在则调用init函数,使用别名的原因是因为驱动里变量名称不固定,Linux不可能去规定开发者们变量该用什么名字或者函数该用什么名字,但可以使用一个固定别名指向它

实现原理

kernel/include/linux/module.h文件大约212行可以找到它的实现:

#ifdef MODULE
/* Creates an alias so file2alias.c can find device table. */
#define MODULE_DEVICE_TABLE(type, name)					\
extern typeof(name) __mod_##type##__##name##_device_table		\__attribute__ ((unused, alias(__stringify(name))))
#else  /* !MODULE */
#define MODULE_DEVICE_TABLE(type, name)
#endif

它会去判断当前是MODULE方式还是静态编译,如果是静态编译到内核里那它就是一个空函数宏,编译到内核里的话将会通过driver namebusid_table的方式来匹配,id_tableMODULE_DEVICE_TABLE的方式一致,只不过一个是模块的方式一个是内核匹配的方式。
它的实现方式也非常简单,就是利用了GCC的属性,在Linux里你可以看到大量与GCC相关的语法特性,不然怎么叫GNU/Linux呢,背靠GNU Tools,其关键语句是这一行extern typeof(name) __mod_##type##__##name##_device_table __attribute__ ((unused, alias(__stringify(name)))),它定义了一个名为 __mod_##type##__##name##_device_table的变量,然后使用了GCCalias属性定义了一个别名:__attribute__ ((unused, alias(__stringify(name))))unused是指这个变量没有使用也不要报警告而__stringify是将宏转化为字符串,与宏#符号作用一致,这样__mod_##type##__##name##_device_table这个变量就与传递进来的变量关联起来了,__mod_##type##__##name##_device_table就相当于是传递来变量的别名,对它的访问都将指向传递进来的变量。
export在这里的用处是将符号导出可见,在GCC在构建时会有符号表,除了基本的C语言内存布局堆栈BSSDATA段等还有符号表,符号表里存放着符号名称以及地址,全局变量默认是不会被记录在符号表的,如果使用export将符号导出那么它就全局可见,将会被记录在符号表里export除了能够将一个非静态全局变量声明出来使用以外还会将其记录在符号表里这样可以被其它程序在运行期间通过符号表查询对应的地址。这样insmod在加载模块时就可以通过检索__mod_*作为前缀来检索想要的数据并进行匹配了。typeof(name)的作用就是为了匹配不同的类型,Linux里不固定设备ID的类型,但大多数都是用of_device_id,当然也有i2c_device_id…,但它们内存布局是一样的,所以可以通过类型转换来访问接口。

Tips
在module_init里也用了同样的方法,但它没有使用export,除了static函数以外任何函数都会被放入符号表

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Spring Boot-IDEA创建spring boot项目方法】
  • EXCEL文件如何批量加密,有什么方法
  • 零基础学习Redis(7) -- hash类型命令使用
  • TCP的流量控制深入理解
  • 92. UE5 GAS RPG 使用C++创建GE实现灼烧的负面效果
  • 【操作系统】同步互斥与Golang互斥锁实现
  • 【TomCat】安装部署
  • 实训day41(9.2)
  • Python读取Excel数据教程 - 详细版
  • HTTPS 通信时是对称加密还是非对称加密?
  • 2024年互联网公司时薪排行榜大曝光!看完我酸了,第一竟是他…
  • 云计算实训40——部署nmt、部署project_exam_system项目
  • 基于深度学习的稀疏感知器设计
  • 使用PyInstaller打包带图标的软件
  • kafak推送消息。
  • [LeetCode] Wiggle Sort
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • css选择器
  • Facebook AccountKit 接入的坑点
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • interface和setter,getter
  • Java,console输出实时的转向GUI textbox
  • JS函数式编程 数组部分风格 ES6版
  • leetcode98. Validate Binary Search Tree
  • React16时代,该用什么姿势写 React ?
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Theano - 导数
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 对JS继承的一点思考
  • 反思总结然后整装待发
  • 使用 Docker 部署 Spring Boot项目
  • 算法系列——算法入门之递归分而治之思想的实现
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 用Canvas画一棵二叉树
  • 在electron中实现跨域请求,无需更改服务器端设置
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #《AI中文版》V3 第 1 章 概述
  • #if等命令的学习
  • #单片机(TB6600驱动42步进电机)
  • (12)Linux 常见的三种进程状态
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (4)事件处理——(7)简单事件(Simple events)
  • (55)MOS管专题--->(10)MOS管的封装
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (图)IntelliTrace Tools 跟踪云端程序
  • (一一四)第九章编程练习
  • (转)大型网站架构演变和知识体系
  • .DFS.
  • .gitignore
  • .Net 6.0 处理跨域的方式
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .net6 webapi log4net完整配置使用流程