6

在所有可加载的内核模块中,当给出它时,make它会生成一个名为modulename.mod.c.modulename.ko

以下代码摘录来自一个.mod.c文件,其中包含一{number, function}对。这个数字有什么意义?这个数字是如何由编译器生成的?

static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {

        { 0xa6d8dcb5, "module_layout" },
        { 0x16c2b958, "register_netdevice" },
        { 0x609f1c7e, "synchronize_net" },
        { 0x90a60c63, "kmem_cache_destroy" },
        { 0x402b8281, "__request_module" },
        { 0x844a8af7, "netdev_info" },
        { 0xdfdb0ee8, "kmalloc_caches" },
        { 0x12da5bb2, "__kmalloc" },
        { 0x92d42843, "cfg80211_cqm_rssi_notify" },
        { 0xc86289e8, "perf_tp_event" },
...
...
}
4

1 回答 1

6

__versions所有单个*.mod.c文件中包含的部分

  CRC         Symbol
{ 0xa6d8dcb5, "module_layout" },
{ 0x16c2b958, "register_netdevice" },
  ...         ...

是符号及其对应 CRC 的列表。这有两个主要用途:

  1. 所有导出符号的全局列表。
  2. 加载ko模块时检查模块版本。

模块版本控制背后的基本原理

模块版本控制由CONFIG_MODVERSIONS标签启用,并用作简单的 ABI 一致性检查。创建导出符号的完整原型的 CRC 值。当一个模块被加载/使用时,内核中包含的 CRC 值与模块中的相似值进行比较;如果它们不相等,内核将拒绝加载该模块,因为这表明该模块是参考不同版本的 Linux 内核源代码构建的。

编译成功后,所有导出符号的所有 CRC 的全局列表存储在Module.symversLinux 内核源目录下的文件中。本质上,此检查确保从内核模块调用的任何导出符号都存在于模块预期的相同位置(内核中的偏移量)。

modpost工具在 Linux 内核编译期间生成 CRC 它由modpost 脚本调用。整个过程在Documentation/kbuild/modules.rst:450中有详细解释。

modpost 工具的完整源代码可在 Linux 内核源代码中找到。add_depends()是负责__versions在每个*.mod.c文件中生成整个部分的相关函数。

于 2013-07-29T12:40:45.973 回答