【问题标题】:What is kernel section mismatch?什么是内核部分不匹配?
【发布时间】:2012-01-23 17:44:56
【问题描述】:

在编译内核模块时,我收到一条警告,其中包含添加编译选项 CONFIG_DEBUG_SECTION_MISMATCH=y 的注释。它为我提供了有关问题的更详细信息:

WARNING: \**\*path to module\***(.text+0x8d2): Section mismatch in reference from the function Pch_Spi_Enable_Bios_Wr() to the variable .devinit.data:ich9_pci_tbl.22939
The function Pch_Spi_Enable_Bios_Wr() references
the variable __devinitdata ich9_pci_tbl.22939.
This is often because Pch_Spi_Enable_Bios_Wr lacks a __devinitdata
annotation or the annotation of ich9_pci_tbl.22939 is wrong.

我找不到确切的内核部分不匹配是什么,更不用说如何修复它了。

【问题讨论】:

    标签: linux module linux-kernel kernel


    【解决方案1】:

    这意味着具有给定生命周期的节中的函数引用了具有不同生命周期的节中的某些内容。

    当内核二进制文件被链接时,代码和数据的不同部分被分成不同的部分。其中一些部分一直保持加载状态,但其他部分在不再需要时被删除(例如,仅在启动期间需要的内容可以在启动完成后释放 - 这可以节省内存)。

    如果一个长期存在的部分中的函数引用了其中一个可丢弃部分中的数据,则会出现问题 - 它可能会在该数据已被释放时尝试访问该数据,从而导致各种运行时问题.

    这不是一个您可以自行修复的警告,除非您编写了该代码或非常熟悉该代码。它通过正确注释函数(或它引用的数据)来修复,以便它进入正确的部分。只有详细了解内核的该部分,才能确定正确的修复程序。


    有关这些部分和注释的列表,请参阅内核源代码树中的 include/linux/init.h 标头:

    /* These macros are used to mark some functions or 
     * initialized data (doesn't apply to uninitialized data)
     * as `initialization' functions. The kernel can take this
     * as hint that the function is used only during the initialization
     * phase and free up used memory resources after
     *
     * Usage:
     * For functions:
     * 
     * You should add __init immediately before the function name, like:
     *
     * static void __init initme(int x, int y)
     * {
     *    extern int z; z = x * y;
     * }
     *
     * If the function has a prototype somewhere, you can also add
     * __init between closing brace of the prototype and semicolon:
     *
     * extern int initialize_foobar_device(int, int, int) __init;
     *
     * For initialized data:
     * You should insert __initdata between the variable name and equal
     * sign followed by value, e.g.:
     *
     * static int init_variable __initdata = 0;
     * static const char linux_logo[] __initconst = { 0x32, 0x36, ... };
     *
     * Don't forget to initialize data not at file scope, i.e. within a function,
     * as gcc otherwise puts the data into the bss section and not into the init
     * section.
     * 
     * Also note, that this data cannot be "const".
     */
    
    /* These are for everybody (although not all archs will actually
       discard it in modules) */
    #define __init      __section(.init.text) __cold notrace
    #define __initdata  __section(.init.data)
    #define __initconst __section(.init.rodata)
    #define __exitdata  __section(.exit.data)
    #define __exit_call __used __section(.exitcall.exit)
    

    其他人紧随其后,有更多的 cmets 和解释。

    另请参阅CONFIG_DEBUG_SECTION_MISMATCH Kconfig 符号的帮助文本:

    部分不匹配分析检查是否存在非法
    从一个部分到另一部分的引用。
    Linux 将在链接期间或运行时删除某些部分
    并且之前在这些部分中对代码/数据的任何使用都将
    最有可能导致糟糕的结果。
    在代码中函数和变量用
    注释 __init、__devinit 等(请参阅 include/linux/init.h 中的完整列表)
    这导致代码/数据被放置在特定部分。
    部分不匹配分析总是在完整之后进行
    内核构建,但启用此选项将另外
    执行以下操作:

    • 将选项 -fno-inline-functions-called-once 添加到 gcc
      在非 init
      中内联注释为 __init 的函数时 函数我们会丢失部分信息,因此
      分析不会捕获非法引用。
      这个选项告诉 gcc 少内联,但也会
      导致更大的内核。
    • 为每个模块/built-in.o 运行节不匹配分析
      当我们在 vmlinux.o 上运行节不匹配分析时,我们
      丢失有关不匹配位置的有价值信息
      介绍。
      为每个模块/built-in.o 文件运行分析
      将告诉不匹配发生的位置更接近
      资源。缺点是我们会报告相同的
      至少两次不匹配。
    • 从 modpost 启用详细报告以帮助解决问题
      报告的部分不匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-19
      相关资源
      最近更新 更多