如何从另一个模块调用导出的内核模块函数? [英] How to call exported kernel module functions from another module?

查看:565
本文介绍了如何从另一个模块调用导出的内核模块函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个API作为内核模块,为设备驱动程序提供各种功能.我在 mycode.c 中编写了三个函数.然后,我构建并加载了模块,然后将 mycode.h 复制到<内核>/include/linux .在设备驱动程序中,我有一个 #include< linux/mycode.h> 并调用这三个函数.但是,在构建驱动程序模块时,我收到三个链接程序警告,指出这些功能未定义.

I'm writing an API as a kernel module that provides device drivers with various functions. I wrote three functions in mycode.c. I then built and loaded the module, then copied mycode.h into < kernel >/include/linux. In a device driver, I have a #include < linux/mycode.h > and call those three functions. But when I build the driver module, I get three linker warnings saying that those functions are undefined.

注意:

  • 函数在mycode.h中声明为 extern .
  • 使用mycode.c中的 EXPORT_SYMBOL(func_name)导出功能.
  • 运行命令nm mycode.ko将所有三个功能显示在符号表中(它们旁边的大写T,表示该符号在文本(代码)部分中找到)
  • 加载模块后,命令 grep func_name/proc/kallsyms 显示正在加载的所有三个函数
  • The functions are declared extern in mycode.h
  • The functions are exported using EXPORT_SYMBOL(func_name) in mycode.c
  • Running the command nm mycode.ko shows all three functions as being available in the symbol table (capital T next to them, meaning the symbols are found in the text (code) section)
  • After loading the module, the command grep func_name /proc/kallsyms shows all three functions as being loaded

因此,很明显,这些函数可以正确导出,并且内核知道它们的含义和位置.那么,为什么驾驶员看不到他们的定义呢?知道我想念什么吗?

So clearly the functions are being exported correctly and the kernel knows what and where they are. So why can't the driver see their definitions? Any idea what am I missing?

我在这里找到了有关此信息: http://www.kernel.org/doc/Documentation/kbuild/modules.txt

有时,外部模块使用从另一个模块导出的符号 外部模块. kbuild需要全面了解所有符号 避免吐出有关未定义符号的警告.三 存在针对这种情况的解决方案.

Sometimes, an external module uses exported symbols from another external module. kbuild needs to have full knowledge of all symbols to avoid spitting out warnings about undefined symbols. Three solutions exist for this situation.

注意:建议使用具有顶级kbuild文件的方法,但可能会 在某些情况下不切实际.

NOTE: The method with a top-level kbuild file is recommended but may be impractical in certain situations.

使用顶级kbuild文件如果您有两个模块,则foo.ko和 bar.ko,其中foo.ko需要来自bar.ko的符号,您可以使用 通用顶级kbuild文件,因此两个模块都在 相同的版本.请考虑以下目录布局:

Use a top-level kbuild file If you have two modules, foo.ko and bar.ko, where foo.ko needs symbols from bar.ko, you can use a common top-level kbuild file so both modules are compiled in the same build. Consider the following directory layout:

  ./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

任何一个模块中的符号知识.

knowledge of symbols from either module.

使用额外的Module.symvers文件构建外部模块后, 生成一个Module.symvers文件,其中包含所有导出的符号 在内核中没有定义.从以下位置访问符号 bar.ko,从bar.ko的编译中复制Module.symvers文件 到构建foo.ko的目录.在模块构建过程中, kbuild将读取目录中的Module.symvers文件. 外部模块,构建完成后, 创建包含所有符号之和的Module.symvers文件 定义,而不是内核的一部分.

Use an extra Module.symvers file When an external module is built, a Module.symvers file is generated containing all exported symbols which are not defined in the kernel. To get access to symbols from bar.ko, copy the Module.symvers file from the compilation of bar.ko to the directory where foo.ko is built. During the module build, kbuild will read the Module.symvers file in the directory of the external module, and when the build is finished, a new Module.symvers file is created containing the sum of all symbols defined and not part of the kernel.

使用"make"变量KBUILD_EXTRA_SYMBOLS如果不切实际, 从另一个模块复制Module.symvers,可以分配一个空格 在构建文件中将文件列表分隔为KBUILD_EXTRA_SYMBOLS. 这些文件将在初始化过程中由modpost加载. 其符号表.

Use "make" variable KBUILD_EXTRA_SYMBOLS If it is impractical to copy Module.symvers from another module, you can assign a space separated list of files to KBUILD_EXTRA_SYMBOLS in your build file. These files will be loaded by modpost during the initialization of its symbol tables.

但是使用所有这三种解决方案时,为了使任何驱动程序使用我的API,它都必须创建一个新的Makefile或直接访问我的Module.symvers文件?这似乎有点不方便.我希望他们能够#include我的头文件并且一切顺利.没有其他替代方法了吗?

But with all three of these solutions, in order for any driver to use my API, it would have to either create a new Makefile or have direct access to my Module.symvers file? That seems a bit inconvenient. I was hoping they'd just be able to #include my header file and be good to go. Do no other alternatives exist?

推荐答案

从我的研究看来,这些是解决这种情况的唯一三种方法,我已经使每种方法都起作用了,所以我想只会从那些中挑选我最喜欢的.

From my research, it seems that those are the only three ways to handle this situation, and I've gotten each of them to work, so I think I'll just pick my favorite out of those.

这篇关于如何从另一个模块调用导出的内核模块函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆