为什么Linux内核模块符号无法正确导出?

时间:2015-10-26 08:39:55

标签: c linux linux-kernel insmod

我们已经编写了许多内核模块和许多导出符号,除了2个符号(这是令人困惑的)之外,它们都能正常工作。我们已经将它们导出为所有其他符号,但是一旦将它们插入内核中,它们就不会全局导出。

在我们的C代码中,我们(在wdt.ko中):

EXPORT_SYMBOL(WDT_Enable);
EXPORT_SYMBOL(WDT_Disable);

如果我们在生成的内核对象上运行nm,它们会正确显示:

nm wdt.ko | grep WDT
00000000 T WDT_Enable
00000000 T WDT_Disable

这应该意味着这些符号是全局导出的。一旦我们insmod内核对象:

# insmod wdt.ko
# insmod apphandler.ko
apphandler: Unknown symbol WDT_Enable
apphandler: Unknown symbol WDT_Disable

如果我们看看kallsyms:

# cat /proc/kallsyms | grep WDT
c12504dc t WDT_Enable  [wdt]
c12502d8 t WDT_Disable [wdt]

一旦它们进入内核,它们就不是全局的。

我们已经确认正在将正确的文件插入到内核中,并且这些函数在同一个模块中可见,但是我们无法解释为什么这些符号突然变为局部,而不像nm所暗示的那样是全局的。

有谁知道我们的错误可能在哪里?

1 个答案:

答案 0 :(得分:1)

好的 - 在发布问题后不久我们注意到我们的包含路径缺少模块包括:

#include <linux/module.h>

代码似乎在没有包含#include的情况下编译文件,并且编译器没有生成错误或投诉,但净效果是后续模块无法使用的符号。

由于包含头文件,上面指出的符号可供模块使用,内核能够解析并执行代码。