【问题标题】:What triggers re-compilation of linux kernel modules什么触发了重新编译linux内核模块
【发布时间】:2013-03-13 05:43:42
【问题描述】:

Linux 内核的模块如此“脆弱”并且需要经常重新编译,这让我有点惊讶。在两台不同的机器(例如不同版本的 gcc)上使用相同的源代码树会产生不适用于内核(机器 B)的模块(机器 A)。

如果我不想要臭名昭著的no symbol version for module_layout 错误消息,添加虚拟系统调用显然也需要重新编译。

更令我惊讶的是,在 kernel/ 中添加了一个仅 .c 文件,它不涉及任何 ABI(即一个独立的函数,它不会导出、使用或更新任何内部结构)。

在新的 .c 文件中添加一个虚拟文本字符串,让所有模块都保持不变。

那么这里的规则和基本原理到底是什么? (我专注于 x86,32 位架构,如果这很重要的话)

【问题讨论】:

  • 不是一个答案,因为它只是一个猜测。基本上,模块需要知道导出函数在内核中的位置。内核是一个位模块,可以在重新编译期间更改。如果您使用完全相同的标志编译完全相同的代码,您将获得相同的模块,因此导出不会被修改。否则模块会中断。文件中的注释在实际编译之前被删除,因此不会造成任何更改。
  • 你的意思是没有针对位于内核本身的表的符号解析?
  • 不,它是在模块与内核链接期间完成的。没有运行时解析,就像在 DLL 中一样。

标签: compilation linux-kernel dependencies kernel-module


【解决方案1】:

您似乎过于关注重建内核和(可加载)模块的编译方面,而忘记了链接。我怀疑您在声明需要“重新编译”时可能夸大了。

更让我惊讶的是,在 kernel/ 中添加了一个仅 .c 文件,它不涉及任何 ABI(即一个独立的函数,它不会导出、使用或更新任何内部结构)

当您将 .c 文件(又名源模块)添加到内核时,新编译的目标文件将需要使用链接器构建新的内核映像。由于没有评估哪些全局内核符号移动或未移动,因此所有(可加载)模块都必须使用新符号映射重新构建(实际上只是重新链接)。不需要对所有内核模块进行“重新编译”;只有 .o 对象文件必须使用新的内核符号映射重新构建到可加载模块中。

为确保(可加载)模块使用匹配的内核和符号映射执行,在加载内核模块时验证版本控制和构建信息。你所说的“脆弱”其实是一种安全措施,用来保证特权模式下执行的代码的完整性。

【讨论】:

  • 感谢您的澄清,是的,我应该使用“重新构建”而不是“重新编译”,因为我没有检查在这些模块上应用了哪些步骤,只是在以前的“制作模块”将不再加载。
猜你喜欢
  • 2011-05-03
  • 1970-01-01
  • 2011-06-06
  • 2016-01-23
  • 2012-02-22
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多