一、问题整理

内核中两个模块,一个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内核如何访问另外一个模块的函数和变量 原创的更多相关文章

  1. Python 包、模块、函数、变量作用域

    Python 项目的组织结构 - 包 -- 模块 --- 类 ---- 函数.变量   Python是利用包和模块来组织一个项目的.   包: 包的物理表现是一个文件夹,但是一个文件夹却不一定是个包, ...

  2. 查看Linux下*.a库文件中文件、函数、变量

    查看Linux下*.a库文件中文件.函数.变量等情况在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t xxx.a 2. ...

  3. Python(五) 包、模块、函数与变量作用域

    一.while循环与使用场景 CONDITION=1 while CONDITION <=5 : CONDITION +=1 print("hello") else: pri ...

  4. 初探linux内核编程,参数传递以及模块间函数调用

    一.前言                                  我们一起从3个小例子来体验一下linux内核编程.如下: 1.内核编程之hello world 2.模块参数传递 3.模块间 ...

  5. Linux内核装载和启动一个可执行程序

    “平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 理解编 ...

  6. linux内核学习之二 一个精简内核的分析(基于时间片轮转)

    一   实验过程及效果 1.准备好相关的代码,分别是mymain.c,mypcb.h,myinterrupt.c ,如下图,make make成功: 在qemu创建的虚拟环境下的运行效果:(使用的命令 ...

  7. Linux内核分析:完成一个简单的时间片轮转多道程序内核代码

    PS.贺邦   原创作品转载请注明出处  <Linux内核分析>MOOC课程    http://mooc.study.163.com/course/USTC-1000029000 1.m ...

  8. Linux内核硬件访问技术

    ① 驱动程序控制设备,主要是通过访问设备内的寄存器来达到控制目的.因此我们讨论如何访问硬件,就成了如何访问这些寄存器. ② 在Linux系统中,无论是内核程序还是应用程序,都只能使用虚拟地址,而芯片手 ...

  9. linux内核中打印栈回溯信息 - dump_stack()函数分析【转】

    转自:http://blog.csdn.net/jasonchen_gbd/article/details/45585133 版权声明:本文为博主原创文章,转载请附上原博链接.   目录(?)[-] ...

  10. 使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】

    关键词:Android  linux hrtimer 蜂鸣器  等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418  作 ...

随机推荐

  1. Bike Sharing Analysis(一)- 探索数据

    1. Bike Sharing Analysis 在这章主要介绍如何分析共享单车服务数据,以及如何基于时间.天气状态特征来识别单车的使用模式.除此之外,我们还会引入可视化分析,假设检验.以及时间序列分 ...

  2. 什么是Selenium Grid?如何搭建Selenium Grid?

    标签(空格分隔): 测试架构 什么是测试基础架构? 测试基础架构指的是,执行测试的过程中用到的所有基础硬件设施以及相关的软件设施.因此,我们也把测试基础架构称之为广义的测试执行环境.通常来讲,测试基础 ...

  3. Me-and-My-Girlfriend-1靶机渗透流程

    Me-and-My-Girlfriend-1 靶机下载 Description: This VM tells us that there are a couple of lovers namely A ...

  4. SpringBoot2.X定时任务schedule

    什么是定时任务和常见定时任务区别? 某个时间定时处理某个任务 发邮件.短信等 消息提醒 统计报表系统 ... 常见定时任务 Java自带的java.util.Timer类配置比较麻烦,时间延后问题 Q ...

  5. VBA | 统计数组某元素出现的次数,适用于一维、二维数组

    很简单的需求,但是中文网络上基本都是循环的方法,经过查找下面的方法很有效.为了方便用户的使用,进行了如下的整改. 1 Sub Statistics_Number_of_occurrences_test ...

  6. 【VMware VCF】VMware Cloud Foundation Part 02:部署 Cloud Builder。

    VMware Cloud Builder 是用于构建 VMware Cloud Foundation 第一个管理域的自动化部署工具,通过将一个预定义信息的 Excel 参数表导入到 Cloud Bui ...

  7. C# 常用类和命名空间

    Array类 用括号声明数组是C#中使用Array类的记号.在后台使用C#语法,会创建一个派生于抽象基类Array的新类.这样,就可以使用Array类为每个C#数组定义的方法和属性了. Array类实 ...

  8. Appium Appium Python API 中文版

    1.contextscontexts(self): Returns the contexts within the current session. 返回当前会话中的上下文,使用后可以识别H5页面的控 ...

  9. hbuilderx生成ios证书和上架全教程

    现在很多公司都使用uniapp作为底层框架来开发app应用,而uniapp的开发工具hbuilderx云打包的时候,需要证书和证书profile文件. 假如是ios应用,则还需要上架到appstore ...

  10. 登录到第一级终端后,如果再次ssh登录到其他终端,SecureCRT标签变更的问题

    "终端->仿真->高级",勾选"忽略窗口标题更改请求"