我有两个驱动程序文件。
dr1.c
dr2.c
dr1.c执行EXPORT_SYMBOL(func1)。
dr2.c通过dr1.h 中的定义使用
dr1和dr2都被编译并创建了对象文件。然而,在内核编译的最后阶段,我遇到了一个错误dr2中func1的未定义引用,但创建了dr2对象文件。
我不明白为什么没有联系。
基本上不会发生链接,因为dr1.c
中定义的func1()
的地址对dr2.c
来说是未知的。
这个问题有两种解决方案:
1.手动将地址告知第二个文件:在这种情况下,让我们假设模块dr1.c
和dr2.c
存在于不同的目录中,并且具有自己的Makefile
。首先,编译dr1
模块。完成后,将Modules.symvers
文件复制到包含dr2.c
的目录中,然后构建dr2
模块。Modules.symvers
基本上包含"导出符号"的地址,通过将其复制到另一个模块的目的地,可以使其"已知",从而最终实现链接。
2.为两个模块使用一个公共Makefile:将dr1.c
和dr2.c
放在同一目录中,并为其创建一个通用内核Makefile
obj-m := dr1.o dr2.o
完成此操作后,将编译这两个文件,生成一个通用的Modules.symvers
文件并相应地进行链接。
希望这能有所帮助。
dr1被编译为一个模块dr2正在被编译到内核中。
因此,链接无法发生,因为dr1不是vmlinux的一部分,即使dr1被编译成一个模块而没有任何错误。我也把dr2做成了一个模块。
此外,我必须确保在配置中启用了内核模块选项。