Build kernel module for existing binary kernel - linux-kernel

How can one build a kernel module that loads into an exiting binary kernel?
It seems that loading depends on the BuildID stored inside the module, but what is needed to match those? I expect the binary kernel to be the result of some git revision, using a default .config (copied from arch/.../configs). How can I decide which revision and .config is needed to build module that would be accepted by the existing kernel?
It seems that matching the of the ARCH and KERNELRELEASE properties as shown by uname -a is not enough.

You will need the source code for the current kernel you are running. These are usually packaged separately (you don't mention your distro). However once done you should be able to build the external module against that kernel following the instructions: Documentation/kbuild/modules.txt

Related

Modifications not taken into account when recompiling linux kernel sources

I want to use the writeprotect mode of the userfaultfd feature, but it is implemented only from Linux 5.11.
I have ubuntu 20 with kernel 5.4 so I installed version 5.11 of Linux from sources, but when I reboot on the installed version, and try to use the writeprotect mode in a c user program the macros (e.g., UFFDIO_WRITEPROTECT) still appear not to be defined. And I verified that userfaultfd is not a module (doing lsmod).
In the other hand, if I make a modification for example in the scheduler just for a test (let's say in kernel/sched/core.c:context_switch) the modification are taken into account because this is in-core, but modifications for user space are not, I'm confused.
The userfaultfd.c file is in the fs/ directory of the kernel.
So please is it something that I'm missing in the compilation process (make menuconfig, make, make modules_install, make) ?
I was wrongly interpreting the error I had.
The modifications are indeed taken into account when I boot on the newly compiled kernel.
But while searching an understanding of what happens when booting on a compiled kernel, I got this:
When booting on a kernel compiled from sources, the libraries in /usr/include are not modified on the disk
If you want to overwrite them by the one modified, you should do this:
make deb-pkg //from the kernel sources directory
cd ..
sudo dpkg -i *.deb
This will install the new kernel and overwrite the headers

Unable to compile a kernel module

I am trying to build a kernel module while compiling the kernel image, by changing the config symbol value to `'m'. But I do not see any module file generated. Please let me know if I need to take some extra steps to generated a module. If I change the flag to 'y' the code works fine.
Also, in online tutorials I have seen both of the following
>insmod temp.ko
also,
>insmod temp.o
Which one is correct type for a dynamically loadable module?
For compiling loadable kernel modules in Linux tree apply the following command
make modules
.ko is the proper kernel module extension. If .o is tried with insmod, then Invalid module format error will be displayed.
if your module has dependencies to other modules, then:
make modules to build modules
make modules_install to install them
modprobe temp.ko to load temp module and it's dependencies
if your module is simple and has no dependencies, then:
make modules to build modules
cd /path/to/module
insmod temp.ko
Wasn't using modules target in make.
First, run make menuconfig, search the module you want to build using /. Next choose 'm' or 'y' depending on when you want to compile it as a part of the kernel or build it as a module.
(If you don't want to build the entire kernel and just a single module):
Next, in the linux directory (assuming you are using vanilla kernel) run the following commands which will generate the scripts and required configuration files based on your .config
make prepare
make scripts
Now simply build the module using:
make M=<path/to/module/dir>
Finally you should have a kernel object/module (.ko) in the directory if you have selected m
hope this helps.

Find correct kernel version to build module

I want to checkout kernel sources to build a kernel module. However when I want to insmod the module I get a "Invalid module format" error. The kernel versions appaerently do not match.
uname -r results in version 3.0.35-gd0fc8d0.
I am on a i.Mx6 Processor and have to checkout a branch from here: https://github.com/boundarydevices/linux-imx6
But I can't seem to find the exact matching kernel version?
You need to build a kernel module against the specific kernel version so that they are compatible with each other.
you should be able to know the kernel version with which a module is built using modinfo command.
#modinfo kernel_mod.ko
look at vermagic field here.
If you are in a hurry, you can try to change Vermagic of kernel module in order to insert the module.
Reference: http://www.linuxquestions.org/questions/linux-kernel-70/how-to-change-the-vermagic-of-a-module-728387/
Or
just google, "Change vermagic of kernel module".
By the way, you should keep in mind that this method can cause a problem.

Cross-compile Linux kernel with additional modules

I am new to cross-compilation. I have to cross-compile a Linux kernel because I intend to use a wifi module with my TS-7500 SBC (ARM processor) and it does not support it. I have the drivers for my wifi module and through internet surfing I have come to know a general procedure of cross-compilation. However I am somewhat confused on the extra module portion. Here is the information from official website of TS-7500 regarding these extra modules:
Appendix - Compiling TS-Kernel with Custom Options
In order to compile a separate kernel module and come out with a .ko file for inclusion in the already existing kernel, these are the steps to take following step 08 and ending at step 09 above. Note: Steps after step 02 are unverified/untested. They represent an accurate procedure which one would go through.
01.) Open menuconfig and modularize the kernel feature using "M". For
example, to modularize cifs.ko, one would use the arrow and Enter keys
to navigate to Filesystems -> Network File Systems -> CIFS Support.
Press "M" to modularize CIFS support into the kernel then keep hitting
"exit" until you're prompted to save changes, choose "yes".
make menuconfig
02.) Compile the kernel with the modules and copy the modules to the Linux PC
make && make modules && make modules_install
03.) Retrieve the module which was copied to the Linux PC with a command like
cp so that it can be installed into the kernel on the MiniSD card.
mkdir /mnt/miniSD4
mount /dev/sdb4 /mnt/miniSD4
cp /lib/modules/2.6.24.4/kernel/fs/cifs/cifs.ko /mnt/miniSD4
04.) Install the module into the kernel by copy and pasting from partition 4
of the card to partition 2 on the SBC.
cp -r /dev/nbd4/cifs.ko /dev/nbd2/lib/modules/2.6.24.4/kernel/fs/cifs/cifs.ko
05.) Finally, in order to use the new module, you must enable it. This can
be included in a startup script such as linuxrc.
depmod
modprobe cifs.ko
I am confused about serial 2. Can anyone explain this to me and where am I supposed to provide address of the drivers I want to install?
Thanks in advance.
I assume that by saying that your SBC does not support it, you mean that the module/driver, that you have cross-compiled, is an 'out of source tree' kernel module.
The above procedure is only for 'in-tree kernel modules'.
This leaves you with following two options.
As a result of cross-compiling the driver, you will have an *.ko file. Transfer this file to the running system using an SD card or through network. After this load the module using
insmod /path/to/module/filename.ko
This method has but one limitation. i.e If this driver/module depends on other drivers, you will have to load them first.
Include you driver in the kernel source tree and use modprobe drivername to load it along with the dependencies. modprobe is more advance than insmod in the sense that it first checks for dependencies and loads them automatically before loading the module itself.
To include the driver in you kernel's source tree see this answer.

Kernel Version Error, insmod fails

I am running with kernel version-2.6.35
When I hit uname -r it gives as 2.6.35-22-generic
Compiled a module from Kernel-2.6.35 source tree,
But it fails to insert the module in my running kernel.
I don't have any clue.
can anybody help me out of this !!
Thank you.
Have to compile LKM against the correct kernel version i.e. output of uname -r. In your case you have downloaded the kernel version-2.6.35 source tree and compiled your LKM against it. While inserting LKM, checks for the KERNEL_VERSION, if they match will not get any errors while module insertion but if they mismatch fails to insert the module.
You want to ensure that CONFIG_MODVERSIONS is enable in the running Kernel, 2.6.35-22-generic in your case. When you the build a Kernel Module from the 2.6.35 sources the running Kernel will allow modules with matching symbols to be loaded or if symbols are missing, it'll fail to load.
Not having CONFIG_MODVERSIONS enabled means that you MUST match the version between the Kernel version and the module.
I am supposing that you are using the official kernel tree, but you are trying to load your module in your distribution. You must you the kernel source/header from your Linux distribution. I am supposing this because of this version 2.6.35-22-generic, -22-generic it is not part of the official version name.

Resources