在Linux内核中,不同模块之间可以通过导出和引用函数或变量的方式来进行交互。具体而言,Linux内核提供了一些导出和引用符号的机制,这些机制可以使得不同模块之间能够访问并使用彼此的函数或变量。
导出符号的方式一般有两种:
- 使用EXPORT_SYMBOL宏,该宏用于导出函数或变量,例如:
/* 在一个模块中定义并导出一个函数 */
void my_function(void) {
/* ... */
}
EXPORT_SYMBOL(my_function);
- 使用EXPORT_SYMBOL_GPL宏,该宏用于导出仅供GPL许可证模块使用的函数或变量,例如:
/* 在一个模块中定义并导出一个仅供GPL许可证模块使用的函数 */
void my_gpl_function(void) {
/* ... */
}
EXPORT_SYMBOL_GPL(my_gpl_function);
引用符号的方式一般有两种:
- 使用extern关键字,该关键字用于声明其他模块中已经导出的函数或变量,例如:
/* 在一个模块中引用一个已经导出的函数 */
extern void my_function(void);
- 使用EXPORT_SYMBOL和EXPORT_SYMBOL_GPL宏的对应头文件,例如:
/* 在一个模块中引用一个已经导出的函数 */
#include <linux/module.h>
#include <linux/kernel.h>
/* 声明要引用的函数 */
extern void my_function(void);
/* 在模块初始化函数中使用该函数 */
static int __init my_module_init(void) {
my_function();
return 0;
}
/* 注册模块初始化函数 */
module_init(my_module_init);
模块导出变量和函数不能重复
不同模块导出的变量名或函数名不能相同。在Linux内核中,导出的符号(变量或函数)的名称必须是全局唯一的,以便不同的模块能够正确地引用和使用这些符号。
如果有多个模块导出了同名的符号,那么链接器会报告符号重复定义的错误,导致内核编译失败。
为了防止符号名重复,内核通常会要求模块开发者在导出符号时,使用模块名或其他特定前缀来命名导出的符号。例如,在一个名为"my_module"的模块中,可以使用"my_module_"作为导出符号的前缀,以确保导出的所有符号都具有唯一的名称。
同时,为了方便模块之间的交互,内核提供了一些机制来避免符号名冲突,例如EXPORT_SYMBOL和EXPORT_SYMBOL_GPL宏。这些宏会将导出的符号名添加到内核的全局符号表中,确保不同模块之间可以正确地引用和使用彼此的符号。
【最后一个bug】多平台都有更新和发布,大家可以一键三连,关注+星标,不错过精彩内容~