2013-03-12 82 views
2

我有点惊讶的是,Linux内核模块是如此的“脆弱”,需要重新编译,所以经常重新编译。在两台不同的机器上使用相同的源代码树(例如不同版本的gcc)生成不能与内核一起工作的模块(机器A)(机器B)。什么引发的linux内核模块

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

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

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

那么究竟什么是规则,这里的原理是什么?我很专注于x86,32位体系结构,如果这很重要的话)

+0

不是因为它的答案只是一个猜测。基本上,模块需要知道导出的函数驻留在内核中的哪个位置。内核是一个可以在重新编译期间更改的模块。如果使用完全相同的标志编译完全相同的代码,则会得到相同的模块,因此导出不会被修改。否则模块会中断。在实际编译之前,文件中的注释会被删除,从而不会引起任何更改。 – Aneri 2013-03-12 11:11:44

+0

你的意思是说,对于坐在内核本身的表没有符号解析? – PypeBros 2013-03-12 12:18:32

+0

不,它是在模块与内核链接期间完成的。没有运行时解析,就像在DLL中一样。 – Aneri 2013-03-13 11:31:42

回答

1

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

令我惊讶更是增加内核仅仅.c文件/,不碰任何ABI(即一个独立的功能,即不出口,使用或更新任何内部结构)

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

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

+0

感谢您的澄清,并且我应该使用“重新构建”而不是“重新编译”,因为我没有检查在这些模块上应用了哪些步骤,只是在之前的“构建模块”中生成的模块会不再加载。 – PypeBros 2013-03-13 13:44:06