Linux内核CONFIG_DEBUG_SECTION_MISMATCH编译错误

15

在Linux内核编译的“make”步骤中,我收到了许多这些错误:

Building modules, stage 2.
MODPOST 2283 modules
WARNING: modpost: Found 1 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'

我知道我可以只运行 make CONFIG_DEBUG_SECTION_MISMATCH=y 来继续进行,但我想知道是否有更好的方法来处理这个问题。也许是向某人报告或者如何自己解决这些问题等等。


2
执行make CONFIG_DEBUG_SECTION_MISMATCH=y花费了约2小时的时间来重建整个内核和模块,只是为了提到一些晦涩的以太网和SCSI驱动程序在其初始化函数中做了一些奇怪的事情。 - PypeBros
1个回答

29

这只是一个警告。内核构建系统进行了一次健全性检查,并发现可能存在错误的代码。警告信息说明,在内核代码中有些代码可能会进行不适当的交叉访问。请注意,您的内核已经构建成功!

要理解此警告的含义,请考虑以下示例:

内核文本段中的某些代码可能会尝试调用标记为__init数据宏的函数,该宏将链接器放置在内核init部分中,在引导或模块加载后被释放。

如果文本段中的代码在初始化代码完成后调用init段中的代码,则可能会出现运行时错误,因为实际上这相当于调用了过时的指针。

尽管如此,该调用可能完全正确——内核text段中的调用可能有一些充分的理由,可以确保仅在确保该函数存在时才调用init段中的函数。

当然,这只是一个例子。类似的其他场景也存在。

解决方法是使用CONFIG_DEBUG_SECTION_MISMATCH=y编译,它会给出哪个函数尝试访问哪个数据或函数以及它们所属的部分的输出。然后,您可以尝试确定构建时的警告是否合理,如果是,则希望能够修复它。

可以使用init.h中的__ref__refdata宏来允许此类init引用而不会产生警告。例如:

char * __init_refok bar(void) 
{
  static int flag = 0;
  static char* rval = NULL;
  if(!flag) {
     flag = 1;
     rval = init_fn(); /* a function discarded after init */
  }
  return rval;
}

__init_refok等可以修复“有效”实例,因此它们存在的事实可能不会激发信心。


__init注释确实让我免去了一个不眠之夜。谢谢。 - Jiri Klouda
1
警告:drivers/net/ethernet/3com/3c509.o(.data+0x11c):变量el3_eisa_driver对函数.init.text:el3_eisa_probe()的引用存在部分不匹配 变量el3_eisa_driver引用了函数__init el3_eisa_probe() 如果引用是有效的,则使用__init或__refdata(请参见linux/init.h)注释变量,或命名变量: _template、_timer、_sht、*_ops、*_probe、*_probe_one、*_console - PypeBros

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接