Linux内核如何访问另外一个模块的函数和变量 原创
一、问题整理
内核中两个模块,一个A,一个B,A模块中有操作函数,B模块要调用A模块的函数。

二、分析
这是一个驱动工程师经常遇到的一个问题,该问题其实是模块符号导出问题,实现该功能比较简单,借助EXPORT_SYMBOL()即可。
1. 什么是符号?
这里的符号主要指的是全局变量和函数,静态全局变量其实也可以被另外一个模块访问到。
2. 为什么要导出符号?
↓
Linux内核采用的是以模块化形式管理内核代码。内核中的每个模块相互之间是相互独立的,也就是说A模块的全局变量和函数,B模块是无法直接访问的。
有些时候,我们写一些模块代码的时候,发现部分函数功能别人已经实现了,此时我们就想如果我们可以调用他们已经实现好的函数接口就好了。那如何才能做到这点呢?
就靠符号导出了,也就是说你可以把你实现的函数接口和全局变量导出,以供其他模块使用。
在Linux内核的世界里,如果一个模块已经以静态的方式编译进的内核,那么它导出的符号就会出现在全局的内核符号表中。
在Ubuntu 14.04系统中,Linux内核的全局符号表存放在以下文件:
/usr/src/linux-headers-3.2.0-29-generic-pae/Module.symvers
如果打开这个文件,可以发现里面的内容就是:
Addr------->符号名------>模块名------>导出符号的宏

3. 如何导出符号?
Linux内核给我们提供了两个宏:
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
上面宏定义的任一个使得给定的符号在模块外可用;
GPL版本的宏定义只能使符号对GPL许可的模块可用;
符号必须在模块文件的全局部分输出,在任何函数之外,因为宏定义扩展成一个特殊用途的并被期望是全局存取的变量的声明。
4. 模块编译时,如何寻找使用的符号?
- a.在本模块中符号表中,寻找符号(函数或变量实现)
- b.在内核全局符号表中寻找
- c.在模块目录下的Module.symvers文件中寻找
5. 案例演示
模块A导出全局变量global_var和函数show两个符号供模块B使用。
A模块
#include <linux/init.h>
#include <linux/module.h>
static int global_var = 100;
static void show(void)
{
printk("show(): global_var =%d \n",global_var);
}
static int hello_init(void)
{
printk("module b :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("yikoulinux");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
B模块
#include <linux/init.h>
#include <linux/module.h>
extern int global_var;
extern void show(void);
static int hello_init(void)
{
printk("module a: global_var= %d\n",global_var);
show();
return 0;
}
static void hello_exit(void)
{
printk("hello_exit \n");
return;
}
MODULE_AUTHOR("yikoulinux");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
调试步骤:
- 1.编译模块A,然后加载模块A,在模块A编译好后,在它的当前目录会看到一个Module.symvers文件,这里存放的就是我们模块A导出的符号。
- 2.将模块A编译生成的Module.symvers文件拷贝到模块B目录下,然后编译模块B,加载模块B。
- 3.通过dmesg查看模块打印的信息。
打印信息如下:

由结果可知,我们在B模块中访问到了模块A的全局变量global_var以及函数show。
更多Linux驱动的知识,请关注公众号:一口Linux
Linux内核如何访问另外一个模块的函数和变量 原创的更多相关文章
- Python 包、模块、函数、变量作用域
Python 项目的组织结构 - 包 -- 模块 --- 类 ---- 函数.变量 Python是利用包和模块来组织一个项目的. 包: 包的物理表现是一个文件夹,但是一个文件夹却不一定是个包, ...
- 查看Linux下*.a库文件中文件、函数、变量
查看Linux下*.a库文件中文件.函数.变量等情况在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t xxx.a 2. ...
- Python(五) 包、模块、函数与变量作用域
一.while循环与使用场景 CONDITION=1 while CONDITION <=5 : CONDITION +=1 print("hello") else: pri ...
- 初探linux内核编程,参数传递以及模块间函数调用
一.前言 我们一起从3个小例子来体验一下linux内核编程.如下: 1.内核编程之hello world 2.模块参数传递 3.模块间 ...
- Linux内核装载和启动一个可执行程序
“平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 理解编 ...
- linux内核学习之二 一个精简内核的分析(基于时间片轮转)
一 实验过程及效果 1.准备好相关的代码,分别是mymain.c,mypcb.h,myinterrupt.c ,如下图,make make成功: 在qemu创建的虚拟环境下的运行效果:(使用的命令 ...
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
PS.贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 1.m ...
- Linux内核硬件访问技术
① 驱动程序控制设备,主要是通过访问设备内的寄存器来达到控制目的.因此我们讨论如何访问硬件,就成了如何访问这些寄存器. ② 在Linux系统中,无论是内核程序还是应用程序,都只能使用虚拟地址,而芯片手 ...
- linux内核中打印栈回溯信息 - dump_stack()函数分析【转】
转自:http://blog.csdn.net/jasonchen_gbd/article/details/45585133 版权声明:本文为博主原创文章,转载请附上原博链接. 目录(?)[-] ...
- 使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】
关键词:Android linux hrtimer 蜂鸣器 等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418 作 ...
随机推荐
- hive第一课:# hive-3.1.2分布式搭建文档
hive-3.1.2分布式搭建文档 谷歌浏览器下载网址:Google Chrome – Download the fast, secure browser from Google 华为云镜像站:htt ...
- ZYNQ:使用SDK打包BOOT.BIN、烧录BOOT.BIN到QSPI-FLASH
打包程序为BOOT.BIN 注意,做好备份是一个好习惯. Vivado Vivado 添加QSPI Flash的IP,重新编译: Launch SDK(推荐方法):或者用SDK指定一个workspac ...
- setsocket、getsocket 函数详解
背景 以前用到socket的时候会调用setsocket进行设置,现在整理有关的笔记的时候,重新查阅资料发现有点奇怪,发现大家比较少使用到这个. setsocket/getsocket #includ ...
- uCos 学习:0-有关概念
先说一下UCOSIII:Micrium在2009年推出了UCOSIII,相对于之前的UCOSII版本,在性能上有了进一步的提升,主要是支持时间片轮调度,极短的关中断事件等. 可剥夺多任务管理: 什么是 ...
- 分享两个内置Google广告位的Typecho主题
前言 很多项目的开始都是因为情怀和热爱,"为爱发电"是一件很值得尊敬的事情,然而大量"为爱发电"的项目最后却不得不因"难以为继"而被迫停服. ...
- VS图片
- power bi创建切片器导航
现在很多报告使用的是按钮导航,今天分享另外一种方式:切片器导航. 第一步: 新建一个页面导航表,主页-输入数据-[填写列名,每页报表的表名] 如图: [页面导航表] 第二步: 添加一个切片器,将页面导 ...
- Vue2 整理(二):核心篇(组件化开发)
前言 上一篇连接:vue2 整理:基础篇. 组件化开发 组件概念 组件,对于学Java的人来说的话,这个词所要表达的意思再熟悉不过了. 所谓组件就是:面向对象中的抽象.封装思想:而所谓的组件化就是:把 ...
- computed 和 watch 的区别和运用的场景?
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值: watch: ...
- Cush:从辞职自学编程到被 Apple、PriceTag推荐
名字:Cush 开发者 / 团队:ShaSha 平台:iOS.macOS 请简要介绍下这款产品 也许你听过记账可以帮助省钱,但总是浅尝辄止? 快试试 Cush!它精简了记账中所有复杂繁琐的步骤,简单精 ...