我有两个内核模块(比如modA和modB)。 modA使用EXPORT_SYMBOL(symA)
导出符号,modB使用它。我有modA的标题modA.h
:
...
extern void symA(int param);
...
和modB.c
:
#include "modA.h"
...
static int __init modB_init(void)
{
symA(10);
}
...
如果i insmod
modB一切正常,我的modB在内核中正确链接,函数symA
被正确调用。但是,当我构建modB时,编译器会发出警告:symA is undefined
。 LKM是ELF可重定位的,为什么编译器会发出此警告?怎么可以删除?
答案 0 :(得分:12)
http://www.kernel.org/doc/Documentation/kbuild/modules.txt
中解释了这个问题(以及如何在这种情况下正确编译)有时,外部模块使用另一个模块中的导出符号 外部模块。 kbuild需要完全了解所有符号 避免吐出有关未定义符号的警告。三 这种情况存在解决方案。
注意:建议使用顶级kbuild文件的方法,但可以 在某些情况下是不切实际的。
使用顶级kbuild文件如果你有两个模块,foo.ko和 bar.ko,其中foo.ko需要来自bar.ko的符号,你可以使用a 常见的顶级kbuild文件,因此两个模块都在 相同的构建。请考虑以下目录布局:
./foo/ <= contains foo.ko ./bar/ <= contains bar.ko The top-level kbuild file would then look like: #./Kbuild (or ./Makefile): obj-y := foo/ bar/ And executing $ make -C $KDIR M=$PWD will then do the expected and compile both modules with full
来自任何一个模块的符号知识。
使用额外的Module.symvers文件构建外部模块时, 生成包含所有导出符号的Module.symvers文件 它们没有在内核中定义。要访问符号 bar.ko,从bar.ko的编译中复制Module.symvers文件 到构建foo.ko的目录。在模块构建期间, kbuild将读取目录中的Module.symvers文件 外部模块,当构建完成时,一个新的 创建Module.symvers文件,其中包含所有符号的总和 已定义,而不是内核的一部分。
使用“make”变量KBUILD_EXTRA_SYMBOLS如果它不切实际 从另一个模块复制Module.symvers,可以分配一个空格 在构建文件中将文件分隔为KBUILD_EXTRA_SYMBOLS。 在初始化期间,这些文件将由modpost加载 它的符号表。