c - 为什么 Linux 内核模块符号不能正确地全局导出?

标签 c linux linux-kernel insmod

我们已经编写了许多内核模块和许多带有导出符号的模块,除了 2 个符号(令人困惑)外,它们都可以正常工作。我们已将它们与所有其他符号一样导出,但是这 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 所建议的那样。

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

最佳答案

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

#include <linux/module.h>

代码似乎在没有包含 #include 的情况下编译文件,并且编译器没有生成错误或投诉,但最终结果是这些符号对后续模块不可用。

由于包含头文件,上述符号可用于模块,内核能够解析和执行代码。

关于c - 为什么 Linux 内核模块符号不能正确地全局导出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33341524/

相关文章:

c - 在链表上插入一个新节点会创建一个新节点

c - 在运行时初始化二维数组并允许用户输入

linux - 每个进程是否都有自己的进程表,或者只有一个进程表仅由内核维护?

c - linux中每个进程的内存监控

c - printf %f 地址错误

c - 如何通过 kprobe 将 BPF 程序附加到内核函数?

c - epoll 返回 0 个事件

python - 通过 Popen 帮助 ping

c++ - C++ 中的短消息 AES 性能

linux -/lib64/ld-linux-x86-64.so.2 : No such file or directory error