2、Linux驱动开发:模块_引用符号
目录
🍅点击这里查看所有博文
随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有一点用处的技巧,用的不多的技巧可能一个星期就忘了。
想了很久想通过一些手段把这些事情记录下来。也尝试过在书上记笔记,这也只是一时的,书不在手边的时候那些笔记就和没记一样,不是很方便。
很多时候我们遇到了问题,一般情况下都是选择在搜索引擎检索相关内容,这样来的也更快一点,除非真的找不到才会去选择翻书。后来就想到了写博客,博客作为自己的一个笔记平台倒是挺合适的。随时可以查阅,不用随身携带。
同时由于写博客是对外的,既然是对外的就不能随便写,任何人都可以看到。经验对于我来说那就只是经验而已,公布出来说不一定我的一些经验可以帮助到其他的人。遇到和我相同问题时可以少走一些弯路。
既然决定了要写博客,那就只能认真去写。不管写的好不好,尽力就行。千里之行始于足下,一步一个脚印,慢慢来 ,写的多了慢慢也会变好的。权当是记录自己的成长的一个过程,等到以后再往回看时,就会发现自己以前原来这么菜😂。
本系列博客所述资料均来自互联网资料,并不是本人原创(只有博客是自己写的)。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。
什么是符号?
这里的符号主要指的是全局变量和函数
Linux内核采用的是以模块化形式管理内核代码。内核中的每个模块相互之间是相互独立的,也就是说A模块的全局变量和函数,B模块是无法访问的。
不同模块间可通过导出宏,将符号导出,被导出的符号可被其他模块使用。
static int num = 100;
static void show(void)
{printk("aaaa: num =%d \n",num);
}
EXPORT_SYMBOL(num);
EXPORT_SYMBOL(show);
Ubuntu中的符号表
Linux内核的全局符号表在/usr/src/linux-headers-xxxxx-generic/Module.symvers。
root@ubuntu:# ls /usr/src/linux-headers-4.15.0-142-generic/
arch crypto firmware init Kconfig Makefile net security ubuntu
block Documentation fs ipc kernel mm samples sound usr
certs drivers include Kbuild lib Module.symvers scripts tools virt
某个单独编译的内核符号表在代码根目录下。在模块编译好后,在它的当前目录会看到一个Module.symvers文件,这里存放的就是我们模块A导出的符号。
root@ubuntu:# ls
helloa.c helloa.mod.c helloa.o modules.order
helloa.ko helloa.mod.o Makefile Module.symvers
示例源码
模块A的示例源码,在模块A中使用EXPORT_SYMBOL导出整型变量num和void型函数show。
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("PD");
static int num = 100;
static void show(void)
{printk("helloa_show num =%d \n",num);
}
static int hello_init(void)
{printk("helloa_init \n");return 0;
}
static void hello_exit(void)
{printk("helloa_exit \n");return;
}
EXPORT_SYMBOL(num);
EXPORT_SYMBOL(show);
module_init(hello_init);
module_exit(hello_exit);
在模块B中直接使用extern引入外部的定义即可。
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("PD");
extern int num;
extern void show(void);
static int hello_init(void)
{printk("hellob_init %d\n",num);show();return 0;
}
static void hello_exit(void)
{printk("hellob_exit \n");return;
}
module_init(hello_init);
module_exit(hello_exit);
引用步骤
编译模块A,将模块A编译生成的Module.symvers文件拷贝到模块 B目录下(可选),不拷贝的话,在编译B时也只是会报一个警告,不影响使用。建议拷贝,程序员不能忽视任何一个警告才是对的。
WARNING: "show" [/home/peng/Desktop/driver/example/2_export/b/hellob.ko] undefined!
WARNING: "num" [/home/peng/Desktop/driver/example/2_export/b/hellob.ko] undefined!
编译模块B,操作正确的情况下,正常是不会有任何的错误和警告的。
root@ubuntu:# make
make -C /lib/modules/4.15.0-142-generic/build M=/home/peng/Desktop/driver/example/2_export/b modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic'CC [M] /home/peng/Desktop/driver/example/2_export/b/hellob.oBuilding modules, stage 2.MODPOST 1 modules
WARNING: "show" [/home/peng/Desktop/driver/example/2_export/b/hellob.ko] undefined!
WARNING: "num" [/home/peng/Desktop/driver/example/2_export/b/hellob.ko] undefined!CC /home/peng/Desktop/driver/example/2_export/b/hellob.mod.oLD [M] /home/peng/Desktop/driver/example/2_export/b/hellob.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic'
先加载模块A,然后加载模块B。从日志中分析可知在加载模块A时,先执行了helloa的加载函数。加载模块B的过程中执行模块B加载函数时,首先引用了模块a的变量num,紧接着又调用了模块A中show函数。
root@ubuntu:# insmod ./helloa.ko
root@ubuntu:# insmod ./hellob.ko
root@ubuntu:# dmesg
[ 8167.354563] helloa_init
[ 8170.907883] hellob_init 100
[ 8170.907884] helloa_show num =100
注意事项
加载的时候,必须先加载A模块,再加载B模块。否则会报错Unknown symbol in module。
root@ubuntu:# insmod ./hellob.ko
insmod: ERROR: could not insert module ./hellob.ko: Unknown symbol in module
root@ubuntu:# insmod ./helloa.ko
root@ubuntu:# insmod ./hellob.ko
卸载的时候,必须先卸载B模块,再卸载A模块。否则会报错Module helloa is in use by。
root@ubuntu:# rmmod ./helloa.ko
rmmod: ERROR: Module helloa is in use by: hellob
root@ubuntu:# rmmod ./hellob.ko
root@ubuntu:# rmmod ./helloa.ko
那么本篇博客就到此结束了,这里只是记录了一些我个人的学习笔记,其中存在大量我自己的理解。文中所述不一定是完全正确的,可能有的地方我自己也理解错了。如果有些错的地方,欢迎大家批评指正。如有问题直接在对应的博客评论区指出即可,不需要私聊我。我们交流的内容留下来也有助于其他人查看,说不一定也有其他人遇到了同样的问题呢😂。
相关文章:
2、Linux驱动开发:模块_引用符号
目录 🍅点击这里查看所有博文 随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记…...
Python web实战 | Docker+Nginx部署python Django Web项目详细步骤【干货】
概要 在这篇文章中,我将介绍如何使用 Docker 和 Nginx 部署 Django Web 项目。一步步讲解如何构建 Docker 镜像、如何编写 Docker Compose 文件和如何配置 Nginx。 1. Docker 构建 Django Web 项目 1.1 配置 Django 项目 在开始之前,我们需要有一个 D…...
【uniapp】实现买定离手小游戏
前言 最近玩了一个小游戏,感觉挺有意思,打算放进我的小程序【自动化小助手】里面,“三张押一张,专押花姑娘!”,从三张卡牌,挑选一张,中奖后将奖励进行发放,并且创建下一…...
【vim 学习系列文章 3 - vim 选中、删除、复制、修改引号或括号内的内容】
文章目录 vim 快捷命令vim 操作符vim 文本对象vim 动作 上篇文章: vim 学习系列文章 2 - vim 常用插件配置 vim 快捷命令 Vim 有一个模块化的结构,允许你使用各种命令的组合操作。大多数命令有两个、三个或四个部分。三部分结构的一个版本是这样的:操作…...
webpack联邦模块介绍及在dumi中使用问题整理
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、ModuleFederationPlugin参数含义?二、如何在dumi中使用及问题整理1. 如何在dumi中使用(这个配置是好使的)2.相关问题整理2.1 问题12.2 问题2 总…...
记录一下Kotlin: Module was compiled with an incompatible version of Kotlin.的问题
我遇到的整个报错是这样的: Error:Kotlin: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.7.1, expected version is 1.1.16. 大概意思就是不匹配,但是我这是个不太能随便改代码的项目&#x…...
html中使用Vue+element UI动态创建表单数据不显示问题
直接上代码:html代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&…...
CentOS下 Docker、Docker Compose 的安装教程
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 Docker Compose是用于定义…...
[OnWork.Tools]系列 02-安装
下载地址 百度网盘 历史版本连接各种版本都有,请下载版本号最高的版本 链接:https://pan.baidu.com/s/1aOT0oUhiRO_L8sBCGomXdQ?pwdn159提取码:n159 个人链接 http://on8.top:5000/share.cgi?ssiddb2012fa6b224cd1b7f87ff5f5214910 软件安装 双…...
【外键合并python】
外键合并(Foreign Key Merge) 外键合并是指在数据库或者数据表中,通过共同的外键将多个数据表合并在一起的操作。在 Excel 表格中,我们可以使用外键来将多个表格合并,类似于数据库中的关联操作。 步骤一:…...
Mongodb SQL 到聚合映射快速参考
SQL 映射 聚合管道允许MongoDB 提供原生聚合功能,对应于 SQL 中许多常见的数据聚合操作。比如:GROUP BY、COUNT()、UNION ALL 测试数据 For MySQL rootlocalhost 14:40:40 [test]> select * from orders; -------------------------------------…...
腾讯云标准型S6/SA3/SR1/S5/SA2服务器CPU处理器大全
腾讯云服务器CVM标准型CPU处理器大全,包括标准型S6、SA3、SR1、S5、S5se、SA2、S4、SN3ne、S3、SA1、S2ne实例CPU处理器型号大全,标准型S6云服务器CPU采用Intel Ice Lake(2.7GHz/3.3GHz),标准型S5采用Intel Xeon Cascade Lake 8255C/Intel Xe…...
idea 关于高亮显示与选中字符串相同的内容
dea 关于高亮显示与选中字符串相同的内容,本文作为个人备忘的同时也希望可以作为大家的参考。 依次修改File-settings-Editor-Color Scheme-General菜单下的Code-Identifier under caret和Identifier under caret(write)的Backgroud色值,可以参考下图。…...
【重点:单例模式】特殊类设计
请设计一个类,只能在堆上创建对象 方式如下: 将构造函数设置为私有,防止外部直接调用构造函数在栈上创建对象。向外部提供一个获取对象的static接口,该接口在堆上创建一个对象并返回。将拷贝构造函数设置为私有,并且…...
智能家居是否可与ChatGPT深度融合?
ChatGPT自2022年面世以来,已为亿万网民提供智能问答服务。然而我们是否曾想到,这一人工智能驱动的聊天机器人,是否可为智能家居赋能? 要实现ChatGPT与智能家居设备之间的无缝对话,单单依靠一台终端是远远不够的。ChatGPT必须…...
LED芯片 VAS1260IB05E 带内部开关LED驱动器 汽车硬灯带灯条解决方案
VAS1260IB05E深力科LED芯片是一种连续模式电感降压转换器,设计用于从高于LED电压的电压源高效驱动单个或多个串联连接的LED。该设备在5V至60V之间的输入电源下工作,并提供高达1.2A的外部可调输出电流。包括输出开关和高侧输出电流感测电路,该…...
微信小程序插件 painter 生成海报、二维码
GitHub 地址:https://github.com/Kujiale-Mobile/Painter 一、引入 将 components/painter 整个文件放到自己项目的 components 中;以组件的形式在页面的 json 文件中引入; 二、使用 <view class"container"><image s…...
Python版day60
84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 class Solution:def largestRectangleArea(self, heights: List[int]) -> i…...
windows C++多线程同步<3>-互斥量
windows C多线程同步<3>-互斥量 概念,如下图: 另外就是互斥对象谁拥有,谁释放 那么一个线程允许多次获取互斥对象吗? 答案是允许,但是申请多次就要释放多次,否则其他线程获取不到互…...
(学习笔记-系统结构)Linux内核与windows内核
内核 计算机是由各种外部硬件设备组成的,比如内存、CPU、硬盘等,如果每个应用都要和这些硬件设备对接通信协议,那这样太累了,所以这个中间人由内核来负责,让内核作为应用连接硬件设备的桥梁,应用程序只关心…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
