Linux Kernel Module (* .ko) inter-kernel compatibility

I have a simple kernel object that I created to check in kernel memory.

If I build it on my 64-bit Ubuntu (3.2) machine, it works fine on that machine. But it will not be insmod on my 64-bit Ubuntu machine (3.9). And vice versa. This gives me the error "-1 Invalid module format" if I try to run it on a kernel kernel other than the one on which I built it.

I thought that insmod dynamically links it to the exported symbol table, and the exported symbol table does not change between kernel versions. (It is being added.)

Can someone tell me how I can build a kernel module (.ko) compatible with future (or past) Linux kernels without having to rebuild it on that kernel?

Here is my make file:

ccflags-y = -g

obj-m + = access_mem.o

all: make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) modules

clean: make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) clean

+6
source share
2 answers

Joe, Ubuntu (3.2) may use the xyz kernel version, but Ubuntu (3.9) may use the xyz1 kernel version. If the kernel versions are different from each other, you need to build / compile your driver with this particular kernel version. If the kernel versions are the same, you do not need to create a driver. The important point is that each driver module is compiled or built using the version.ko module (which actually enters information about the kernel version built using the driver module), and when loading the kernel module, it checks this information and the kernel version if it differs then throws "- 1 Invalid module format" or if it matches, then the module of the module loads successfully. To develop a kernel module that is future or backward compatible, you need to know on which version of the kernel the API or functions signature for ex has been changed : the ioctl signature has been changed from kernel version 2.3.36 onwards , so your code should be lower

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) static long minor_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) #else static int minor_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) #endif 

If you designed in this way, your kernel module will be compatible with the future or vice versa. Compatibility is just an adaptation of an API signature or functions, etc. changes to the kernel version, retaining the old API or function signature, etc. in your kernel module, as in the example above, but still you need to build / compile the kernel module against the version of the kernel you are trying to load onto.

+5
source

I am not an expert on this, but I am sure that you must create your own driver for each version of the kernel. Regarding characters that remain unchanged between kernel versions, I am pretty sure that this is not the case after reading https://www.kernel.org/doc/Documentation/stable_api_nonsense.txt .

+1
source

Source: https://habr.com/ru/post/951226/


All Articles