如何解决模块间依赖关系?

时间:2013-12-05 22:32:51

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

当两个模块都在内核树之外构建并且启用了modversion时,如何解析模块间依赖关系?

Modversioning用于确保二进制可加载模块与它们加载的内核兼容。它使用.config选项CONFIG_MODVERSIONS启用。

我们有两个动态加载的内核模块,其中一个使用另一个的导出符号。虽然依赖于另一个的模块是在另一个之后加载的,但是insmod抱怨它无法解决依赖。

[FWIW,这些特定的模块在开源世界中没有用处。设计这些模块的人喜欢将它们排除在内核树之外,以用于自己的SCM目的。将这些部署为内核补丁的解决方案将无效。]

这是内核日志显示的内容。

<4>foomod: no symbol version for bar_api
<4>foomod: Unknown symbol bar_api

但是,如果我cat / proc / kallsyms,bar_api就在那里并显示为导出。

此处的另一位开发人员建议我们使用.conf文件从loadmodules脚本调用,该脚本忽略此错误并强制加载,如下所示。

install foomod { /sbin/modprobe --ignore-install --force-modversion foomod
$CMDLINE_OPTS; }

我认为必须有一种更清洁的方法来解决这个问题。

我尝试修改Makefile以引用导出符号的模块的symvers。每个模块源都在对等目录中。这似乎并不重要,但我可能做错了。

KBUILD_EXTRA_SYMBOLS := ../barmod/Module.symvers

这是Module.symvers的内容:

0x00000000 bar_api  bar_api     barmod

假设0x00000000在禁用modversion时有效。我想如果我可以像这样使用modprobe并查看导出的函数,那么modprobe就会成功。但是,这仅在禁用模拟时才有效。

# modprobe --dump-modversions foomod.ko
0x00000000      bar_api

但是,将两个驱动程序复制到内核树中并从中构建工作。这是用校验和引用的符号的部分列表。

# modprobe --dump-modversions foomod.ko
0x46085e4f      add_timer
0x7d11c268      jiffies
0x6a9f26c9      init_timer_key
0x7ec9bfbc      strncpy
0xe43dc92b      misc_register
0x3302b500      copy_from_user
0x85f8a266      copy_to_user
0xc6538cfc      bar_api
0xea147363      printk
   :              :

回到〜2002年,有了CONFIG_MODVERSIONS会导致构建将genksyms生成的校验和附加到每个导出的内核函数。符号看起来像这样: printk_R1b7d40 。这是我最后一次处理modversion,因为我以后的所有工作都是使用开源代码,库存内核代码,或者禁用modversioning。但是,今天的构建使用genksyms为进入特殊部分的每个符号创建校验和。检查此特殊部分的校验和匹配。

曾经有一个名为EXPORT_SYMBOL_NOVERS()的内核宏可以使用,但已被弃用。

使用的Linux内核是2.6.32。

我发现这些文章相关且有用,但没有定论:

http://lxr.free-electrons.com/source/Documentation/kbuild/modules.txt

http://lwn.net/Articles/21393/

http://www.linuxchix.org/content/courses/kernel_hacking/lesson8

http://lwn.net/Kernel/LDD2/ch11.lwn


如何在可加载模块中干净地导出某个函数,并且当它们都在Linux内核之外构建时,允许它由另一个可依赖的可加载模块使用?

0 个答案:

没有答案