什么是内核部分不匹配? [英] What is kernel section mismatch?

查看:122
本文介绍了什么是内核部分不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编译内核模块时,我得到一个警告,并带有添加编译选项 CONFIG_DEBUG_SECTION_MISMATCH = y 的注释.它为我提供了有关问题的更多详细信息:

When compiling a kernel module, I got a WARNING with a note to add a compile option, CONFIG_DEBUG_SECTION_MISMATCH=y. It give me more detailed info about issue:

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.

我找不到确切的内核部分不匹配,更不用说如何解决它了.

I could not find what exactly kernel section mismatch is, not to mention how to go about fixing it.

推荐答案

这意味着具有给定生命周期的节中的函数引用具有不同生命周期的节中的某些东西.

It means that a function that is in a section with a given lifetime references something that is in a section with a different lifetime.

链接内核二进制文件时,代码和数据的不同部分分为不同的部分.这些部分中的某些部分始终保持加载状态,而其他部分则在不再需要时被删除(例如,仅在引导过程中需要的内容可以在引导完成后释放,这可以节省内存).

When the kernel binary is linked, different parts of the code and data are split up into different sections. Some of these sections are kept loaded all the time, but some others are removed once they are no longer needed (things that are only required during boot for example can be freed once boot is done - this saves memory).

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

If a function that is in a long-lasting section refers to data in one of the discardable sections, there is a problem - it might try to access that data when it has already been released, leading to all kinds of runtime issues.

这不是警告,除非您已编写该代码或对其非常熟悉,否则您将自行修复.通过正确注释功能(或它所引用的数据)对其进行修复,以使其进入正确的部分.正确的解决方案只能通过对内核那部分的详细了解来确定.

This is not a warning you'll fix yourself, unless you wrote that code or are very familiar with it. It gets fixed by correctly annotating the function (or the data it refers to) so that it goes into the right section. The right fix can only be determined with detailed knowledge of that part of the kernel.

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

For a list of these sections and annotations, refer to the include/linux/init.h header in your kernel source tree:

/* 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)

其他人,还有更多评论和解释.

Others follow, with more comments and explanations.

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

See also the help text for the CONFIG_DEBUG_SECTION_MISMATCH Kconfig symbol:

部分不匹配分析检查是否存在非法
从一个部分到另一部分的引用.
Linux将在链接或运行时删除一些部分
以及之前在这些部分中对代码/数据的任何使用都会
最有可能导致哎呀.
在代码中,函数和变量用
注释 __init,__ devinit等(请参见include/linux/init.h中的完整列表)
导致将代码/数据放置在特定部分中.
区段不匹配分析总是在完整的
之后执行 内核构建,但启用此选项还将另外
请执行以下操作:

The section mismatch analysis checks if there are illegal
references from one section to another section.
Linux will during link or during runtime drop some sections
and any use of code/data previously in these sections will
most likely result in an oops.
In the code functions and variables are annotated with
__init, __devinit etc. (see full list in include/linux/init.h)
which results in the code/data being placed in specific sections.
The section mismatch analysis is always done after a full
kernel build but enabling this option will in addition
do the following:

  • 将选项-fno-inline-functions-called-once添加到gcc
    当在非init中内联带有注解__init的函数时
    函数,我们将丢失版块信息,因此
    分析将不会捕获非法引用.
    此选项告诉gcc减少内联,但也会
    导致更大的内核.
  • 运行每个模块/内置模块的部分不匹配分析.
    当我们在vmlinux.o上运行部分不匹配分析时,我们
    丢失有关不匹配位置的有价值的信息
    介绍.
    对每个模块/内置.o文件运行分析
    会告诉您不匹配发生的位置更接近
    来源.缺点是我们将报告相同的
    至少两次不匹配.
  • 启用来自modpost的详细报告以帮助解决
    报告的部分不匹配.
  • Add the option -fno-inline-functions-called-once to gcc
    When inlining a function annotated __init in a non-init
    function we would lose the section information and thus
    the analysis would not catch the illegal reference.
    This option tells gcc to inline less but will also
    result in a larger kernel.
  • Run the section mismatch analysis for each module/built-in.o
    When we run the section mismatch analysis on vmlinux.o we
    lose valueble information about where the mismatch was
    introduced.
    Running the analysis for each module/built-in.o file
    will tell where the mismatch happens much closer to the
    source. The drawback is that we will report the same
    mismatch at least twice.
  • Enable verbose reporting from modpost to help solving
    the section mismatches reported.

这篇关于什么是内核部分不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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