Linux内核为vmlinux提供了未定义的引用,但编译了.o文件

时间:2014-10-27 21:56:13

标签: c linux linux-kernel makefile linux-device-driver

我有2个驱动程序文件。

dr1.c

dr2.c

dr1.c执行EXPORT_SYMBOL(func1)。

dr2.c通过dr1.h

中的定义使用它

编译dr1和dr2并创建目标文件。 但是,在内核编译的最后阶段,我收到一个错误 dr2中func1的未定义引用,但是创建了dr2目标文件。

我不明白为什么链接没有发生。

2 个答案:

答案 0 :(得分:1)

基本上没有发生链接,因为func1()中定义的dr1.c地址dr2.c是未知的。

这个问题有两种解决方案:

<强> 1。手动将地址公布到第二个文件: 在这种情况下,让我们假设模块dr1.cdr2.c存在于不同的目录中并且拥有自己的Makefile。首先,编译dr1模块。完成后,将Modules.symvers文件复制到包含dr2.c的目录,然后构建dr2模块。 Modules.symvers基本上包含“导出符号”的地址,通过将其复制到另一个模块的目标,您将其“已知”,从而最终发生链接。

<强> 2。对两个模块使用通用的Makefile: 将dr1.cdr2.c放在同一目录中,并为其创建一个公共内核Makefile。在Makefile中输入以下条目:

obj-m := dr1.o dr2.o

完成此操作后,两个文件都将被编译,生成一个共同的Modules.symvers文件,并相应地进行链接。

希望这会有所帮助。

答案 1 :(得分:0)

dr1正在编译为模块 dr2正被编译到内核中。

因此,链接不会发生,因为dr1不是vmlinux的一部分,即使dr1编译成模块没有任何错误。我也把dr2变成了一个模块。

另外,我必须确保在配置中启用了内核模块选项。