Compilation 什么触发了linux内核模块的重新编译

Compilation 什么触发了linux内核模块的重新编译,compilation,linux-kernel,dependencies,kernel-module,Compilation,Linux Kernel,Dependencies,Kernel Module,我有点惊讶,Linux内核的模块如此“脆弱”,需要经常重新编译。在两台不同的机器(例如不同版本的gcc)上使用相同的源代码树会生成与内核(机器B)不兼容的模块(机器A) 如果我不希望模块布局出现臭名昭著的无符号版本的错误消息,那么添加虚拟系统调用显然也需要重新编译 更让我吃惊的是,在kernel/中只添加了一个.c文件,它不涉及任何ABI(即,一个独立的函数,不导出、使用或更新任何内部结构) 在这个新的.c文件中添加一个伪文本字符串可以使所有模块保持不变 那么,这里的规则和理由到底是什么呢? (

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

如果我不希望模块布局出现臭名昭著的
无符号版本的错误消息,那么添加虚拟系统调用显然也需要重新编译

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

在这个新的.c文件中添加一个伪文本字符串可以使所有模块保持不变

那么,这里的规则和理由到底是什么呢?
(我的重点是x86,32位体系结构,如果这很重要的话)

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

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

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


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

不是答案,因为这只是猜测。基本上,模块需要知道导出函数在内核中的位置。内核是位模块,在重新编译期间可能会更改。如果使用完全相同的标志编译完全相同的代码,则会得到相同的模块,因此导出不会被修改。否则模块会损坏。文件中的注释在实际编译之前被删除,因此不会造成任何更改。您的意思是没有针对内核中的表的符号解析吗?不,它是在模块与内核链接期间完成的。没有运行时解析,就像在DLL中一样。感谢您的澄清,是的,我应该使用“重新构建”而不是“重新编译”,因为我没有检查在这些模块上应用了哪些步骤,只是在以前的“生成模块”中生成的模块将不再加载。