如何构建 Linux 内核模块以使其与所有内核版本兼容? [英] How to build a Linux kernel module so that it is compatible with all kernel releases?

查看:29
本文介绍了如何构建 Linux 内核模块以使其与所有内核版本兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to build a kernel module that will be compatible with all the kernel’s releases. For example, if I build a kernel module on kernel 3.2.0-29 and try to load it on 3.2.0-86, I get the following error:

modprobe my_driver

modprobe my_driver

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

FATAL: Error inserting my_driver (/lib/modules/3.2.0-86-generic/kernel/fs/my_drv/my_drv.ko): Invalid module format

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

[ In the log messeges: my_drv: disagrees about version of symbol module_layout ]

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

How can I build a kernel module on 3.2.0-29 that will be good for all 3.2.0 releases.

推荐答案

简而言之:你很难可以编写有用的内核模块,这些模块可以加载到相对多种版本.

In short: you hardly can write useful kernel module, which can be loaded to kernels of relatively wide range of versions.

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

When you build the module against kernel compiled with CONFIG_MODVERSIONS (like in your case), for every symbol, exported from the kernel, CRC for this symbol is stored in module's file. CRC is some sort of control sum, which takes into account, among other things, layout of types, used for function's parameters. For example, if layout of a hypothetical struct A differs in two kernels, CRC for function f(struct A *a) in these kernels differs too.

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

When a module is loaded into running kernel, CRC for all functions in the module are compared with ones for the kernel. If they differ, the kernel refuses to load the module. To read more about this mechanism see the kernel's documentation (Documentation/kbuild/modules.txt).

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

So, for make a module loadable into two different kernels, you are restricted only with functions whose parameters have same layout in both kernels. In particular, if layout of type struct module differs, no single module can be loaded for both kernels.

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

There are several approaches to deliver a driver suitable for several kernels. The simplest way is to deliver the driver's sources and add them to dkms. Such a way, if running kernel doesn't have the driver built, the driver will be compiled automatically using its sources.

这篇关于如何构建 Linux 内核模块以使其与所有内核版本兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆