返回顶部
首页 > 资讯 > 操作系统 >Linux内核怎样访问另外一个模块的函数和变量
  • 506
分享到

Linux内核怎样访问另外一个模块的函数和变量

2023-06-15 15:06:45 506人浏览 薄情痞子
摘要

今天就跟大家聊聊有关linux内核怎样访问另外一个模块的函数和变量,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、问题整理内核中两个模块,一个A,一个B,A模块中有操作函数,B模块

今天就跟大家聊聊有关linux内核怎样访问另外一个模块的函数和变量,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

一、问题整理

内核中两个模块,一个A,一个B,A模块中有操作函数,B模块要调用A模块的函数。

Linux内核怎样访问另外一个模块的函数和变量

二、分析

这是一个驱动工程师经常遇到的一个问题,该问题其实是模块符号导出问题,实现该功能比较简单,借助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------->符号名------>模块名------>导出符号的宏

 Linux内核怎样访问另外一个模块的函数和变量

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);

调试步骤:

编译模块A,然后加载模块A,在模块A编译好后,在它的当前目录会看到一个Module.symvers文件,这里存放的就是我们模块A导出的符号。

将模块A编译生成的Module.symvers文件拷贝到模块B目录下,然后编译模块B,加载模块B。

通过dmesg查看模块打印的信息。打印信息如下:

Linux内核怎样访问另外一个模块的函数和变量

由结果可知,我们在B模块中访问到了模块A的全局变量global_var以及函数show。

看完上述内容,你们对Linux内核怎样访问另外一个模块的函数和变量有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网操作系统频道,感谢大家的支持。

--结束END--

本文标题: Linux内核怎样访问另外一个模块的函数和变量

本文链接: https://lsjlt.com/news/280588.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Linux内核怎样访问另外一个模块的函数和变量
    今天就跟大家聊聊有关Linux内核怎样访问另外一个模块的函数和变量,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、问题整理内核中两个模块,一个A,一个B,A模块中有操作函数,B模块...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作