我正在编写一个API作为内核模块,为设备驱动程序提供各种功能.我在mycode.c中写了三个函数.然后我构建并加载了模块,然后将mycode.h复制到<kernel>/include/linux中.在设备驱动程序中,我有一个#include <linux/mycode.h>并调用这三个函数.但是当我构建驱动程序模块时,我得到三个链接器警告,说明这些函数是未定义的.
笔记:
很明显,函数正在正确导出,内核知道它们的位置和位置.那么为什么司机不能看到他们的定义呢?知道我错过了什么吗?
编辑:我在这里找到了一些相关的信息: http ://www.kernel.org/doc/Documentation/kbuild/modules.txt
有时,外部模块使用来自另一个外部模块的导出符号.kbuild需要完全了解所有符号,以避免吐出有关未定义符号的警告.这种情况存在三种解决方案.
注意:建议使用顶级kbuild文件的方法,但在某些情况下可能不切实际.
使用顶级kbuild文件如果你有两个模块,foo.ko和bar.ko,其中foo.ko需要来自bar.ko的符号,你可以使用一个通用的顶级kbuild文件,所以这两个模块都是用同一个编译的建立.请考虑以下目录布局:
Run Code Online (Sandbox Code Playgroud)./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访问符号,请将module.symvers文件从bar.ko的编译复制到构建foo.ko的目录.在模块构建期间,kbuild将读取外部模块目录中的Module.symvers文件,并且在构建完成时,将创建一个新的Module.symvers文件,其中包含已定义的所有符号的总和,而不是内核的一部分.
使用"make"变量KBUILD_EXTRA_SYMBOLS如果从另一个模块复制Module.symvers是不切实际的,则可以在构建文件中将空格分隔的文件列表分配给KBUILD_EXTRA_SYMBOLS.这些文件将在其符号表初始化期间由modpost加载.
但是对于所有这三种解决方案,为了让任何驱动程序使用我的API,它必须创建一个新的Makefile或直接访问我的Module.symvers文件?这看起来有点不方便.我希望他们能够#include我的头文件并且好好去.不存在其他替代方案吗?
我想检查Linux内核导出的符号列表.所以我解雇命令,
# cat /proc/kallsyms
0000000000000000 D per_cpu__irq_stack_union
0000000000000000 D __per_cpu_start
0000000000004000 D per_cpu__gdt_page
0000000000005000 d per_cpu__exception_stacks
000000000000b000 d per_cpu__idt_desc
000000000000b010 d per_cpu__xen_cr0_value
000000000000b018 D per_cpu__xen_vcpu
000000000000b020 D per_cpu__xen_vcpu_info
000000000000b060 d per_cpu__mc_buffer
000000000000c570 D per_cpu__xen_mc_irq_flags
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出.我的问题是,这个输出中每个字段的含义是什么?第一个字段看起来像地址,我没有获得第二个字段的任何引用.任何人都可以向我解释第二场中值D,d,t,T,s的含义吗?
我为内核开发了两个简单的模块.现在我想在一个模块中定义一个函数,然后在另一个模块中使用它.
我怎么能这样做?
只需在其他模块中定义函数和调用程序而不会出现问题?
当我收到此错误时,我将一些驱动程序嵌入到Linux内核中(我在板文件中添加设备并注册它):
error: 'kxtf9_get_slave_descr' undeclared here (not in a function)
Run Code Online (Sandbox Code Playgroud)
我将上面的函数放在驱动程序文件中
struct ext_slave_descr *kxtf9_get_slave_descr(void)
{
return &kxtf9_descr;
}
EXPORT_SYMBOL(kxtf9_get_slave_descr);
Run Code Online (Sandbox Code Playgroud)
它不应该由EXPORT_SYMBOL"可见"吗?包含上面代码的C文件没有头文件(我没有写它,我只是在这里找到它并且我正在实现.他们说它已经过测试所以我假设不需要头文件?
其余代码编译完美(因此它"看到"文件夹中的代码),包含上面代码的文件也编译完成!