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

查看:233
本文介绍了如何构建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是某种 control sum ,它特别考虑了用于函数参数的类型布局.例如,如果两个内核中假设的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与内核的功能进行比较.如果它们不同,则内核拒绝加载模块.要了解有关此机制的更多信息,请参阅内核的文档( 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天全站免登陆