Linux内核中的模块间通信

Linux内核中的模块间通信,linux,kernel,Linux,Kernel,我有两个Linux内核模块,其中一个可以为另一个提供一些功能。但该功能的使用不是必需的,即使第一个模块不存在,第二个模块也可以(并且应该)工作 如果我只是从第一个模块导出函数并在第二个模块中使用它,那么第二个模块依赖于该符号,没有第一个模块就无法加载 解决方案之一是让用户脚本为第一个模块中的函数查找/proc/kallsym,如果存在,脚本将其地址作为参数传递给第二个模块,然后由第二个模块生成指针。但我不喜欢这种解决方案,原因很明显 如果有更正确、更优雅的解决方案,允许第二个模块获取第一个模块中

我有两个Linux内核模块,其中一个可以为另一个提供一些功能。但该功能的使用不是必需的,即使第一个模块不存在,第二个模块也可以(并且应该)工作

如果我只是从第一个模块导出函数并在第二个模块中使用它,那么第二个模块依赖于该符号,没有第一个模块就无法加载

解决方案之一是让用户脚本为第一个模块中的函数查找/proc/kallsym,如果存在,脚本将其地址作为参数传递给第二个模块,然后由第二个模块生成指针。但我不喜欢这种解决方案,原因很明显


如果有更正确、更优雅的解决方案,允许第二个模块获取第一个模块中某个符号的地址,但避免硬依赖?

我认为如果模块B依赖于模块A,那么如果没有先加载模块A,则无法成功加载模块B

事实上,只有在先插入模块A之后,从模块A导出的模块B所需的符号才会出现在/proc/kallsym文件中


这种情况的解决方案是:在模块B中,module_init()函数应该有一些代码来检查模块A是否已经存在,如果没有,请先加载模块A。i、 e.使用request_module()来加载,或者创建一个更奇特的方法来使用try_然后再使用request_module()。

最后我找到了解决方案:内核有symbol_get()和symbol_put(),这让我有机会在另一个模块中查找任意符号(当然需要导出)并防止在我使用其符号时卸载模块。

有更优雅的解决方案,但需要更改内核。基本上,内核被增强以容纳模块注册。当一个模块被加载并想要向其他模块公开自己时,他将使用一个众所周知的int注册到内核中——这只是内核数组中的一个索引,用于存储对已注册模块的引用。现在,任何想要获取对另一个模块的引用的模块都只需向内核请求对该模块的新引用——使用相同的、众所周知的int。这些新引用必须是短期的(即,您获得对它的引用,但将其放回同一上下文中)。为了实现长寿命的连接,您必须在两个模块之间建立协议,以便当任一模块卸载时,他/她知道如何通知另一个模块他/她要离开。

即使没有模块a,模块B也需要工作(假设a提供了一个与机器上不存在的某个硬件加速的接口).在2.4中有一个query_module()接口,它几乎完全满足了我的需要,但在2.6中被删除了。我想知道是否有替代品。。。