一尘不染

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

linux

我想构建一个将与所有内核发行版兼容的内核模块。例如,如果我在内核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)时出错:无效的模块格式

[在日志消息中:my_drv:对符号module_layout的版本持不同意见]

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


阅读 618

收藏
2020-06-07

共1个答案

一尘不染

简而言之 :您 几乎 无法编写有用的内核模块,该模块可以加载到相对广泛的版本的内核中。

当针对编译时使用的内核构建模块时CONFIG_MODVERSIONS(如您的情况),对于从内核导出的每个符号,该符号的CRC都存储在模块文件中。CRC是某种
控制总和 ,除其他事项外,还考虑了用于函数参数的类型布局。例如,如果假设的布局struct A在两个内核f(struct A *a)中不同,则这些内核中功能的CRC也将不同。

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

因此,为了使一个模块可加载到两个不同的内核中,您仅受参数在两个内核中具有相同布局的函数的限制。特别是,如果类型的布局struct module不同,则无法为两个内核加载单个模块。


有几种方法可以交付适用于多个内核的驱动程序。最简单的方法是交付驱动程序的
并将其添加到中dkms。这样,如果正在运行的内核没有构建驱动程序,则将使用其源代码 自动 编译驱动程序。

2020-06-07