Linux驱动学习之模块化,参数传递,符号导出
1.模块化
1.1.模块化的基本概念:
- 模块化是指将特定的功能或组件独立出来,以便于开发、测试和维护。在Linux设备驱动中,模块化允许将驱动程序作为内核模块动态加载到系统中,从而提高了系统的灵活性和可扩展性。
1.2.Linux内核模块的特点:
- 动态加载和卸载:内核模块可以在系统运行时被动态加载或卸载,而无需重新编译整个内核。
- 更好的扩展性:系统可以根据需要加载或卸载模块,从而避免资源的浪费。
- 易于管理和维护:模块化的设计使得驱动程序的开发、测试和部署更加便捷
1.3.模块化的好处
- 独立:模块之间可以独立开发。
- 隔离:驱动模块与内核隔离,不需要改内核源码,不然来一个需求改一次内核源码,风险增加,而且编译内核,换内核都是相对麻烦(当然使用ftp导入内核没什么)。
1.4.驱动模块主要由以下几个部分组成:
模块加载函数(必须):当通过insmod命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块相关初始化工作;
模块卸载函数(必须):当通过rmmod命令卸载模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相反的功能;
模块许可证声明(必须):模块许可证(LICENCE)声明描述内核模块的许可权限,如果不声明LICENCE,模块被加载时将收到内核被污染的警告。大多数
模块参数(可选):模块参数是模块被加载的时候可以被传递给他的值,它本身对应模块内部的全局变量;
模块导出符号(可选):内核模块可以导出符号(symbol,对应于函数或变量),这样其他模块可以使用本模块中的变量或函数;
模块作者等信息声明(可选)。
2.驱动模块的相应接口
参数
@name 变量名
@describe描述信息的字符串
EXPORT_SYMBOL_GPL(name);
// “GPL v2” 是指明 这仅声明为GPL的第二版本
// "GPL and addtional"
// "Dual BSD/GPL"
// "Dual MPL/GPL"
// "Proprietary" 私有的
注意:除非你的模块显式地声明一个开源版本,否则内核会默认你这是一个私有的模块(Proprietary)。
其他接口:
MODULE_DESCRIPTION("描述") // 对这个模块作一个简单的描述,modinfo可以查看
MODULE_VERSION // 这个模块的版本
MODULE_ALIAS // 这个模块的别名
MODULE_DEVICE_TABLE // 告诉用户空间这个模块支持什么样的设备,当系统检测到匹配这些ID设备时,就可以自动加载这个模块
3.测试以及测试解释
3.1.模块化接口测试

该测试用例没有加模块协议,运行会报“模块许可证“未指定”污染内核”,所以该加还是加上。

3.2.参数传递
#include <linux/init.h>
#include <linux/module.h>
static unsigned int var=0;
module_param(var,uint,0664);static char *string;
module_param(string,charp,0444);
MODULE_PARM_DESC(var, "int value");
MODULE_PARM_DESC(string, "str value");static int hello_init(void)
{printk("hello my drivce \r\n");printk("int value %u \r\n", var);printk("str value %s \r\n", string);return 0;
}
static void hello_exit(void)
{printk("hello_exit \r\n");printk("int value %u \r\n", var);printk("str value %s \r\n", string);return;
}MODULE_AUTHOR("seven");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
MODULE_DESCRIPTION("module test.");
测试:
加载驱动可以传递参数如:(insmod 01_module_test.ko string="seven" var=10),这里初始化的时候不设置参数,通过修改 /sys/module/01_module_test/parameters/变量名 这个文件去修改对应的值,然后卸载程序的时候打印出来看看。

3.3.符号导出
a驱动代码(a驱动导出符号给b驱动使用)
#include <linux/init.h>
#include <linux/module.h>
static int global_var = 100;
static void show(void)
{printk("a module show(): global_var =%d \n",global_var);
}
static int hello_init(void)
{printk("a module export :global_var=%d\n",global_var);return 0;
}
static void hello_exit(void)
{printk("hello_exit \n");return;
}EXPORT_SYMBOL(global_var);
EXPORT_SYMBOL(show);
MODULE_AUTHOR("seven");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
b驱动代码:
#include <linux/module.h>extern int global_var;
extern void show(void);
static int hello_init(void)
{printk("module b: global_var= %d\n",global_var);global_var--;show();printk("module b: global_var= %d\n",global_var);global_var--;show();return 0;
}
static void hello_exit(void)
{printk("hello_exit \n");return;
}
MODULE_AUTHOR("seven");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
运行时候

3.3.1.b驱动的注意事项
b驱动编译需要依赖 a驱动的符号表(Module.symvers),解决这种问题,目前知道两种办法:
方法1:将a驱动下面的Module.symvers拷贝到b驱动构建目录下面,再进行编译
方法2:makefile里面加上,KBUILD_EXTMOD=构建a驱动的绝对路径
模块编译时,寻找使用的符号
- a.在本模块中符号表中,寻找符号(函数或变量实现)
- b.在内核全局符号表中寻找
- c.在模块目录下的Module.symvers文件中寻找
参考:
手把手教Linux驱动1-模块化编程_要求:掌握linux模块编程技术,了解linux驱动编程与编译。 内容: 第一步(必做):在li-CSDN博客
手把手教Linux驱动2-之模块参数和符号导出_linux 引用其他模块导出来的符号-CSDN博客
内核Module.symvers文件揭秘 - Linux内核编程 | 宅学部落 (zhaixue.cc)
Linux设备驱动的模块化之路-CSDN博客
linux 内核模块声明 MODULE_LICENSE_module liciense-CSDN博客
相关文章:
Linux驱动学习之模块化,参数传递,符号导出
1.模块化 1.1.模块化的基本概念: 模块化是指将特定的功能或组件独立出来,以便于开发、测试和维护。在Linux设备驱动中,模块化允许将驱动程序作为内核模块动态加载到系统中,从而提高了系统的灵活性和可扩展性。 1.2.Linux内核模…...
RabbitMQ02-RebbitMQ简介及交换器
一. AMQP协议 什么是AMQP协议 AMQP(Advanced Message Queuing Protocol,高级消息队列协议):它是进程之间传递异步消息的网络协议 AMQP工作过程 发布者通过发布消息,通过交换机,交换机根据路由规则将收到的消息分发交换机绑定的下消息队列,最…...
Matlab自学笔记三十:元胞数组的修改、添加、删除和连接
1.说明 元胞数组的子数组或元素也是元胞型的,其元素内容(值)是本身类型,因此,在添、删、改和连接处理时,必须明确每个元素的值的类型和大小,否则,编程报错是不可避免的了。看本文前…...
【LeetCode】数组——双指针法
1 双指针法 1.1 介绍 双指针法是一种常用的算法技巧,通常用于处理数组或链表中的问题。它使用两个指针,通常一个从数组的开始位置遍历,另一个从数组的末尾位置开始遍历,根据问题的不同,这两个指针可以同时移动&#…...
react 低代码平台方案汇总
React作为当前最流行的前端框架之一,其生态系统中孕育了多种低代码平台方案,旨在加速应用开发过程。以下是几款基于React的低代码平台或工具,它们通过可视化构建、预制组件、数据绑定等功能,帮助开发者快速构建应用程序࿱…...
oss对象上传文件设置格式
PostMapping("upload")ApiOperation(value "上传文件")public Result<UploadDTO> upload(RequestParam("file") MultipartFile file) throws Exception {if (file.isEmpty()) {return new Result<UploadDTO>().error(ModuleErrorCo…...
【Linux学习】进程
下面是有关进程的相关介绍,希望对你有所帮助! 小海编程心语录-CSDN博客 目录 1. 进程的概念 1.1 进程与程序 1.2 进程号 2. 进程的状态 2.1 fork创建子进程 2.2 父子进程间的文件共享 3. 进程的诞生与终止 3.1 进程的诞生 3.2 进程的终止 1. 进…...
Python数据分析实验四:数据分析综合应用开发
目录 一、实验目的与要求二、主要实验过程1、加载数据集2、数据预处理3、划分数据集4、创建模型估计器5、模型拟合6、模型性能评估 三、主要程序清单和运行结果四、实验体会 一、实验目的与要求 1、目的: 综合运用所学知识,选取有实际背景的应用问题进行…...
基于51单片机的盆栽自动浇花系统
一.硬件方案 工作原理是湿度传感器将采集到的数据直接传送到ADC0832的IN端作为输入的模拟信号。选用湿度传感器和AD转换,电路内部包含有湿度采集、AD转换、单片机译码显示等功能。单片机需要采集数据时,发出指令启动A/D转换器工作,ADC0832根…...
SpirngMVC框架学习笔记(一):SpringMVC基本介绍
1 SpringMVC 特点&概述 SpringMVC 从易用性,效率上 比曾经流行的 Struts2 更好 SpringMVC 是 WEB 层框架,接管了 Web 层组件, 比如控制器, 视图, 视图解析, 返回给用户的数据格式, 同时支持 MVC 的开发模式/开发架构SpringMVC 通过注解,…...
实现信号发生控制
1. 信号发生器的基本原理 信号发生器是一种能够产生特定波形和频率的电子设备,常用于模拟信号的产生和测试。 信号发生器的基本原理 信号发生器的工作原理基于不同的技术,但最常见的类型包括模拟信号发生器和数字信号发生器(DDS࿰…...
二叉树基于队列实现的操作详解
一、队列知识补充 有关队列的知识请详见博主的另一篇博客:http://t.csdnimg.cn/3PwO4 本文仅仅附上需要的队列操作供读者参考 //结构体定义 typedef struct BinaryTreeNode* QDataType;typedef struct QueueNode {struct QueueNode* next;QDataType val; }QNode;…...
LabVIEW常用开发架构有哪些
LabVIEW常用开发架构有多种,每种架构都有其独特的特点和适用场合。以下是几种常用的开发架构及其特点和适用场合: 1. 单循环架构 特点: 简单易用适用于小型应用将所有代码放在一个循环中 适用场合: 简单的数据采集和处理任务…...
告别 Dart 中的 Future.wait([])
作为 Dart 开发人员,我们对异步编程和 Futures 的强大功能并不陌生。过去,当我们需要同时等待多个 future 时,我们依赖 Future.wait([]) 方法,该方法返回一个 List<T>。然而,这种方法有一个显着的缺点࿱…...
Cisco ASA防火墙抓包命令Capture
在日常运维中,遇到故障时经常需要在ASA上抓包进行诊断。 从抓包中可以看到流量是否经过ASA流量是否被ASA放行,或block,匹配的哪一条ACL capture在Firepower平台上同样适用,无论跑的是ASA还是FTD 1 抓包命令 capture 2 配置方…...
Linux网络编程:HTTP协议
前言: 我们知道OSI模型上层分为应用层、会话层和表示层,我们接下来要讲的是主流的应用层协议HTTP,为什么需要这个协议呢,因为在应用层由于操作系统的不同、开发人员使用的语言类型不同,当我们在传输结构化数据时&…...
HTTP 协议中 GET 和 POST 有什么区别?分别适用于什么场景?
HTTP 协议中 GET 和 POST 是两种常用的请求方法,它们的区别如下: 1. 参数传递方式不同 GET 请求参数是在 URL 中以键值对的形式传递的,例如:http://www.example.com/?key1value1&k ey2value2。 而 POST 请求参数是在请求体中以键值对的…...
talib 安装
这里写自定义目录标题 talib 安装出错 talib 安装出错 https://github.com/cgohlke/talib-build/releases 这里找到轮子 直接装。...
echarts-树图、关系图、桑基图、日历图
树图 树图主要用来表达关系结构。 树图的端点也收symbol的调节 树图的特有属性: 树图的方向: layout、orient子节点收起展开:initialTreeDepth、expandAndCollapse叶子节点设置: leaves操作设置:roam线条:…...
04Django项目基本运行逻辑及模板资源套用
对应视频链接点击直达 Django项目用户管理及模板资源 对应视频链接点击直达1.基本运行逻辑Django的基本运行路线:视图views.py中的 纯操作、数据返回、页面渲染 2.模版套用1.寻找一个好的模版2.模板部署--修改适配联动 OVER,不会有人不会吧不会的加Q1394…...
博客标题:智契通项目开发周记(第一周):架构设计与基础环境搭建
一、 本周工作概述 本周是项目实训的第一周,核心目标并非实现具体的业务功能,而是进行顶层设计与地基建设。基于《智契通》项目需求,我们确立了“Spring Boot 3 Vue 3 AI”的技术路线。 主要工作分为两个维度: 架构设计&#…...
深入理解Snaffler规则引擎:如何自定义分类器提升检测效率
深入理解Snaffler规则引擎:如何自定义分类器提升检测效率 【免费下载链接】Snaffler a tool for pentesters to help find delicious candy, by l0ss and Sh3r4 ( Twitter: /mikeloss and /sh3r4_hax ) 项目地址: https://gitcode.com/gh_mirrors/sn/Snaffler …...
基于LM2596的Buck电路设计
目录: 一、详细的说明 二、设计过程 1、手动计算 2、TI工具设计 三、Layout与散热 1、Layout 2、散热 四、PCBA实测 一、详细说明 LM2596 系列稳压器是为降压开关稳压器提供所有有效功能的单片集成电路,能够驱动 3A 的负载,并且拥有…...
Cursor Pro免费使用终极指南:绕过试用限制的完整解决方案
Cursor Pro免费使用终极指南:绕过试用限制的完整解决方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your …...
生物感知层级与真实维度跃迁理论 ——基于三场正交统一论与电磁神经学的生命认知重构
摘要:本文以三场正交统一论(电磁场为主导、引力场与强弱力相位场正交耦合)与电磁神经学(神经元树突为电磁场收发天线、潜意识为全域场处理器、显意识为集中式符号网关)为底层框架,系统性重构生物感知器官的…...
如何实现跨平台VSDX文件无缝协作?drawio-desktop全攻略
如何实现跨平台VSDX文件无缝协作?drawio-desktop全攻略 【免费下载链接】drawio-desktop Official electron build of draw.io 项目地址: https://gitcode.com/GitHub_Trending/dr/drawio-desktop 在数字化协作日益频繁的今天,跨平台文件兼容性问…...
ISPS编程语言HLS设计
一、ISPS编程语言HLS设计 1.ISPS 并非现代主流编程语言 2.ISPS 全称为 Instruction Set Processor Specifications(指令集处理器规范),是一种用于描述数字系统结构和行为的早期硬件描述语言 3.ISPS 属于第二代硬件描述语言&…...
Linux内核SLUB调试之slabinfo工具
前面我们介绍了Linux内核SLUB调试功能,现在我们来介绍一下slabinfo等相关的工具,这对于理解并调试slab缓存功能很有帮助。 slabinfo介绍 slabinfo 不是普通系统命令,而是内核源码自带的官方调试工具。 它的源码位于内核源码树的tools/mm/slabinfo.c,由内核社区直接维护,…...
解决中文文献管理痛点:茉莉花插件如何提升学术研究效率
解决中文文献管理痛点:茉莉花插件如何提升学术研究效率 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 副标题&#x…...
GNOME-BOXES虚拟机快速上手:从安装到共享文件全攻略
1. GNOME-BOXES初体验:为什么选择它? 第一次接触GNOME-BOXES是在我需要临时运行一个Windows应用的时候。作为一个长期使用Linux的用户,我一直在寻找一个既轻量又简单的虚拟机方案。试过VirtualBox,也用过VMware,但要么…...
