Linux源码 EXPORT_SYMBOL

阅读数:195 评论数:0

跳转到新版页面

分类

Linux

正文

一、概述

在Linux内核中,EXPORT_SYMBOL宏允许内核模块导出符号(通常是函数或变量),使得其他模块可以在它们自己的代码中使用这些符号。这是一种模块间通信的机制,允许模块共享代码而不需要将代码复制到每个模块中。

例如,如果一个内核模块实现了一个特定的功能,它可以通过EXPORT_SYMBOL导出一个函数,然后其他模块就可以调用这个函数,而不需要知道其具体实现。这样可以减少代码冗余,并允许模块之间解耦合。

下面是一个简单的示例,说明了如何使用EXPORT_SYMBOL

#include <linux/module.h>

// 一个简单的函数,我们希望其他模块能够使用
int my_shared_function(int arg) {
    printk(KERN_INFO "my_shared_function was called with arg = %d\n", arg);
    return arg + 1;
}

// 使用EXPORT_SYMBOL宏导出my_shared_function
EXPORT_SYMBOL(my_shared_function);

// 模块初始化函数
static int __init my_module_init(void) {
    printk(KERN_INFO "My module loaded\n");
    return 0;
}

// 模块卸载函数
static void __exit my_module_exit(void) {
    printk(KERN_INFO "My module unloaded\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple example module with exported symbol");

在这个例子中,函数my_shared_function被导出,其他加载到内核的模块就可以声明并使用这个函数。需要注意的是,使用EXPORT_SYMBOL导出的符号可以被任何模块使用,不论模块的许可证是什么。如果你想要限制只有GPL兼容的模块才能使用这个符号,那么应该使用EXPORT_SYMBOL_GPL宏。

要使用导出的符号,其他模块需要在它们的代码中声明它们想要使用的外部符号。例如:

extern int my_shared_function(int arg);

然后,这个模块就可以调用my_shared_function,就像它是本地定义的一样。

二、源码相关

查看linux/export.h文件:

struct kernel_symbol //内核符号结构
{
unsigned long value; //该符号在内存地址中的地址
const char *name; //该符号的名称
};

预备知识:

1、#运算符,##运算符

通常在宏定义中使用#来创建字符串 #abc就表示字符串“abc”等。

##运算符称为预处理器的粘合剂,用来替换粘合两个不同的符号,

如:#define xName (n) x##n

则xName(4) 则变为x4

2、gcc的__attribute__属性:

__attribute__((section("section_name")))的作用是将指定的函数或变量放入到名为“section_name”的段中。

__attribute__属性添加可以在函数或变量定义的时候直接加入到定义语句中。

如:int myvar __attribute__((section("mydata"))) = 0;

表示整形变量myvar=0;并且将该变量存放到名为“mydata”的section中。

 

示例分析:如调用EXPORT_SYMBOL(myfc)

展开为__EXPORT_SYMBOL(myfc," ")

继续展开为:

static const char __kstrtab_myfc[]
__attribute__((section("__ksymtab_strings"), aligned(1))) \
= VMLINUX_SYMBOL_STR(myfc);

static const struct kernel_symbol __ksymtab_myfc \
__used \
__attribute__((section("___ksymtab" sec "+" #sym), used)) \
= { (unsigned long)&sym, __kstrtab_myfc }

定义了一个字符数组__kstrtab_myfc[]用于存放导出的符号名myfc。

定义了一个内核符号结构__ksymtab_myfc用于存放引出符号myfc在内存中的地址和名称

 

总结: 在内核符号导出中,调用了EXPORT_SYMBOL(sym), 则会完成以下操作:

(1) 定义一个字符数组存放内核符号的名称,并放置到"__ksymtab_strings"的section中.

(2)定义一个内核符号结构用于存放导出符号的内存地址和名称,并放置到"__ksymatab"中.

即通过EXPORT_SYMBOL(sym)先放了内核以外的世界关于这个符号两点信息: 内核符号的名称和其内存地址.




相关推荐

一、概述 1、为什么Linus不使用GPLv3 在 PC 上,只要你得到了某个程序的源代码,就可以自行编译生成二进制程序,然后替换掉原有的二进制程序,你的程序自由很容易得到保证。然而 iPod、iPh

说明:这种方式只是用于方便阅读代码,因为可以在源代间快速索引跳跃。但是最后可能会有一些warning,可以不必关心,如果是强迫症,可以使用下面这种方式来去掉。

一、概述 在Linux系统中,/usr/bin和/usr/local/bin是两个常见的目录,用于存放可执行文件(二进制文件)。 很多应用都安装在/usr/local下面,先看一下automake工具

  一、概述 vmstat命令是最常见的Linux/Unix监控工具,可以监控给定时间间隔服务器的CPU使用率、内存使用、IO情况。相比top命令,可以查看到整个机器的CPU、内存、IO的使用情况,而

一、概述 sar,System Activity Reporter。是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁

一、简介 简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。 二、使用方法 1、基本语法  awk '条件类型1 {动作1} 条件类型2{动作2} ...

一、概述 列出目标目录中所有的子目录和文件。 二、 语法 ls [选项] [目录名] -a, –all 列出目录下的所有文件,包括以 . 开头的隐含文件 -A 同-a,但不列出“.”(表示当前目录)

一、概述 cd全称是change directory,用于切换当前工作目录。 注意的是,cd命令是一个内建命令,它是由 shell 提供的。因此,不同的 shell 可能会有一些差异,但基本的用法和功

一、概述 全称为print working directory,查看”当前工作目录“的完整路径,一般情况下不带任何参数 二、语法 pwd [选项] -L 即logical,逻辑路径 -P 即

一、概述 通过 mkdir 命令可以实现在指定位置创建以 DirName(指定的文件名)命名的文件夹或目录。要创建文件夹或目录的用户必须对所创建的文件夹的父文件夹具有写权限。并且,所创建的文件夹(目录