Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build a Linux kernel module so that it is compatible with all kernel releases?

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

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

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

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

like image 531
kobi Avatar asked May 08 '16 09:05

kobi


People also ask

Is it possible to build a new Linux kernel?

So, building a new kernel is not a good option as it will require : building kernel building modules and firmware building headers Moving all of above things in appropriate location (if your machine is not same on which you are going to develop module)

Is it possible to write a kernel module?

In short: you hardly can write useful kernel module, which can be loaded to kernels of relatively wide range of versions. 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.

What are the components of Linux kernel?

The terminal lists all Linux kernel components: memory management, hardware device drivers, filesystem drivers, network drivers, and process management. 2. Install the required modules with this command: 3. Finally, install the kernel by typing: The GRUB bootloader is the first program that runs when the system powers on.

How to make a module loadable into two different kernels in Linux?

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. There are several approaches to deliver a driver suitable for several kernels.


1 Answers

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

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.

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).

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.


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.

like image 198
Tsyvarev Avatar answered Nov 01 '22 07:11

Tsyvarev