内核模块:仅当设置了特定参数时才为extern

时间:2019-05-16 11:15:13

标签: linux linux-kernel linux-device-driver

我想使用另一个内核模块中定义的函数。 通常,您这样做如下:

另一个模块

void do_sth() {
  /* ... */
}
EXPORT_SYMBOL(do_sth);

我的模块

extern void do_sth();

void some_function(void) {
  /* ... */
  do_sth();
  /* ... */

}

就我而言,如果安装了do_sth(),或者为我的模块设置了特定的参数(例如other_module,我只想使用功能use_other_module=y

问题是,-当我将函数声明为extern(全局)时-当未安装或加载other_module时,模块将无法再加载。

所以我的问题是:

  • 是否可以确定是否在运行时导出符号?
  • 是否可以从函数内部将符号全局定义为外部符号?

1 个答案:

答案 0 :(得分:0)

根据Ian Abbott的评论,这是一种可能的解决方案:

my_module 中:

  1. 将函数声明为extern,否则编译器将抱怨symbol_get()中的do_sth

    extern void do_sth();
    
  2. 声明一个指针,该指针稍后将指向另一个模块中的函数do_sth

    void (*__do_sth)();
    
  3. 分配指针,增加使用计数器,以便内核知道有人正在使用其他模块

    __do_sth = symbol_get(do_sth);
    if (__do_sth)
        __do_sth();
    
  4. 在移除模块时,或者在不再需要其他模块时,可能更早:减少使用计数器。否则,将无法删除另一个模块,因为内核认为它仍在使用中

    if (__do_sth)
        symbol_put(do_sth);
    
  5. 此外,您还必须确保根据需要以某种方式加载了另一个模块,为此我使用了UDEV规则。