如何构建Linux内核模块以使其与所有内核版本兼容?

kob*_*obi 5 linux linux-kernel

我想构建一个与所有内核版本兼容的内核模块.例如,如果我在内核3.2.0-29上构建内核模块并尝试在3.2.0-86上加载它,我会收到以下错误:

modprobe my_driver

致命错误:插入my_driver时出错(/lib/modules/3.2.0-86-generic/kernel/fs/my_drv/my_drv.ko):模块格式无效

[在log messeges中:my_drv:不同意符号module_layout的版本]

如何在3.2.0-29上构建一个适用于所有3.2.0版本的内核模块.

Tsy*_*rev 5

简而言之:你很难写出有用的内核模块,它可以加载到相对广泛版本的内核中。

当您针对使用编译的内核构建模块时CONFIG_MODVERSIONS(就像在您的情况下一样),对于从内核导出的每个符号,该符号的 CRC 存储在模块的文件中。CRC 是某种控制 sum,它考虑了用于函数参数的类型布局等。例如,如果假设的布局struct A在两个内核f(struct A *a)中不同,则这些内核中函数的 CRC也不同。

当一个模块被加载到正在运行的内核中时,模块中所有函数的 CRC 都会与内核的 CRC 进行比较。如果它们不同,内核将拒绝加载模块。要了解有关此机制的更多信息,请参阅内核文档(Documentation/kbuild/modules.txt)。

因此,要使模块可加载到两个不同的内核中,您只能使用其参数在两个内核中具有相同布局的函数。特别是,如果类型布局struct module不同,则不能为两个内核加载单个模块。


有多种方法可以提供适用于多个内核的驱动程序。最简单的方法是提供驱动程序的并将它们添加到dkms. 这样,如果运行的内核没有构建驱动程序,驱动程序将使用其源代码自动编译。