内核模块:仅当设置了特定参数时才外部
kernel module: extern only if a specific parameter is set
我想使用另一个内核模块中定义的函数。
通常你这样做:
其他模块
void do_sth() {
/* ... */
}
EXPORT_SYMBOL(do_sth);
my_module
extern void do_sth();
void some_function(void) {
/* ... */
do_sth();
/* ... */
}
在我的例子中,如果安装了 other_module
,我只想使用函数 do_sth()
,或者,如果为我的模块设置了特定参数(例如 use_other_module=y
)
问题是 - 一旦我将函数声明为 extern
(全局) - 当未安装或加载 other_module
时,模块无法再加载。
所以我的问题是:
- 有没有办法确定符号是否在运行时导出?
- 有没有办法在函数内部将符号全局定义为 extern?
根据 Ian Abbott 的评论,这是一种可能的解决方案:
在my_module:
将函数声明为extern,否则编译器会报错do_sth in symbol_get()
extern void do_sth();
声明一个指针,稍后将指向另一个模块中的函数do_sth
void (*__do_sth)();
分配指针,递增使用计数器以便内核知道有人正在使用其他模块
__do_sth = symbol_get(do_sth);
if (__do_sth)
__do_sth();
在删除模块时,或者在您不再需要其他模块时更早:减少使用计数器。否则将无法删除另一个模块,因为内核认为它仍在使用中
if (__do_sth)
symbol_put(do_sth);
此外,您必须确保其他模块已按需加载,我为此使用了 UDEV 规则。
我想使用另一个内核模块中定义的函数。 通常你这样做:
其他模块
void do_sth() {
/* ... */
}
EXPORT_SYMBOL(do_sth);
my_module
extern void do_sth();
void some_function(void) {
/* ... */
do_sth();
/* ... */
}
在我的例子中,如果安装了 other_module
,我只想使用函数 do_sth()
,或者,如果为我的模块设置了特定参数(例如 use_other_module=y
)
问题是 - 一旦我将函数声明为 extern
(全局) - 当未安装或加载 other_module
时,模块无法再加载。
所以我的问题是:
- 有没有办法确定符号是否在运行时导出?
- 有没有办法在函数内部将符号全局定义为 extern?
根据 Ian Abbott 的评论,这是一种可能的解决方案:
在my_module:
将函数声明为extern,否则编译器会报错do_sth in symbol_get()
extern void do_sth();
声明一个指针,稍后将指向另一个模块中的函数do_sth
void (*__do_sth)();
分配指针,递增使用计数器以便内核知道有人正在使用其他模块
__do_sth = symbol_get(do_sth); if (__do_sth) __do_sth();
在删除模块时,或者在您不再需要其他模块时更早:减少使用计数器。否则将无法删除另一个模块,因为内核认为它仍在使用中
if (__do_sth) symbol_put(do_sth);
此外,您必须确保其他模块已按需加载,我为此使用了 UDEV 规则。