【发布时间】:2016-01-25 07:16:20
【问题描述】:
我们编写了许多内核模块,其中许多带有导出的符号,除了 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 建议的那样全局。
有人知道我们的错误可能在哪里吗?
【问题讨论】:
-
由
nm和/proc/kallsyms显示的全局可见性,并不意味着其他模块的可用性,由@987654331 控制@,见例如这个answer。此外,对于由一个模块定义的 make 符号在另一个模块中可用,仅EXPORT_SYMBOL是不够的。您需要在同一目录中构建两个模块,或者在第二个模块的 makefile 中使用KBUILD_EXTRA_SYMBOLS变量:stackoverflow.com/a/32949236/3440745。 -
是的 - 同意您的 cmets,并且如前所述,我们的其他符号都在工作。我们定义 WDT 的一个 C 文件不包括下面的头文件。我们确实在同一个地方构建了所有模块,并且每个模块都有一个“通用”构建文件模板。
标签: c linux linux-kernel insmod