Cross-compile Linux kernel with additional modules - linux-kernel

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.

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

Adding only one driver to linux kernel

I know that on the internet I can find same information about "adding one driver to linux kernel" but I can not get it working.
I need to compile an ADV7800driver. It is based on adv7180 driver code.
I put my driver file (adv7800.c) into /linux_source_folder/drivers/media/platform/mxc/capture folder. I also add
adv7800_converter-objs := adv7800.o
obj-$(CONFIG_MXC_ADV7800_CONVERTER)+=adv7800_converter.o
in makefile in the same folder and add information in Kconfigfile.
Then I go back to /linux_source_folder and do sudo make menuconfig and set adv7800 as a module and save config. Then sudo make defconfig, then sudo make -j4 modules (now waiting about 2 hours) and then sudo make modules install.
As a result I can see every module which I configure in menuconfig but I can not see my own module (only .c file exists).
How can I do this correctly and how can I build only this one module without building others (to same much time) ?
I do not remember exactly what happens in terms of instructions executed, but the idea of defconfig is to set a default configuration for a given architecture/platform.
If, as you said, you run sudo make defconfig after you configure your module to be compiled, most likely you loose your configuration. The defconfig should be executed first (once) and then you customize the configuration.
Regarding the compilation of a single module, I point you to an old answer
How to "make" existing Linux kernel module driver after modifying the driver source code.
One note: you should not use sudo to compile

Linux wifi backports cross compile

I am trying to backport Linux wifi drivers from 3.11 to linux-omap-l1(2.6.39). I set up the cross compiler on my Ubuntu 11.4 (kernel is 2.6.38-11-generic) and verified that the cross-compiled kernel can run on an ARM processor as expected. I also was able to backport the wifi drivers to this Ubuntu by following the "Usage Guide" section. However, I have problem to cross compile the wifi backports. Here are two attempts I did:
Attempt#1
Following the "Cross compiling" section from the same link above, I set ARCH(=arm), CROSS_COMPILER, KLIB_BUILD(=linux-omap-l1 directory) and KLIB(=linux-omap-l1 directory), ran make defconfig-wifi, then ran make -j4. It finished without any error. However when I check the generated ko files, they are apparently not cross compiled because they look like "rt2x00usb.ko: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped"
Attempt#2
Then I cleaned the old make result and passed the above four macros directly to make as arguments and ran it again. This time it reported many errors complaining of missing printk.h, atomic.h and average.h
Please help with either of the cases above.
Well, I here post the rt2800usb wifi solution for other's reference. The following steps cross-compiled successfully:
Menuconfig linux-omap-l1(2.6.39) kernel to disable Networking Support -> Wireless, build it and boot it to the embedded unit to ensure the readiness
Run “make mrproper” from the backports directory on the build pc (Ubuntu 11.4)
Run the following sript from the build pc. Ensure the KLIB pointed directory pre-exists, otherwise create it
set -a
CROSS_COMPILE="/opt/arm-2009q1/bin/arm-none-linux-gnueabi-"
ARCH=arm
KLIB_BUILD="/home/xxx/linux-omap-l1"
KLIB="/home/xxx/linux-omap-l1/updates"
set +a
make defconfig-wifi
make oldconfig # menuconfig worked here too
make
make install
Copy the compiled binaries and modules into the unit(10.11.2.3)
scp -r /home/xxx/linux-omap-l1/updates/lib/modules/2.6.39.4-00537-g6c21e4a root#10.11.2.3:/lib/modules/2.6.39.4/.
Log into the embedded unit and run “modprobe -v -f rt2800usb”
Download and install rt2800usb firmware to the /lib/firmware if necessary
lsmod to verify the driver can be loaded
insert the usb dongle (the udev rules may need to be created or modified)
use iw to further examine its properties
backports is unable to pickup my kernel config.....mac80211 is set to module in my kernel config, when I search for mac80211 in backport's menu config, it shows disabled. Tried the above....
set -a
CROSS_COMPILE="/opt/freescale/usr/local/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-none-linux-gnueabi-"
ARCH=arm
KLIB_BUILD="/home/xxx/rpm/BUILD/linux"
KLIB="/home/xxx/rootfs/lib/modules/2.6.35.3-998-ga1cd8a7/updates"
set +a
make defconfig-wifi
make menuconfig
I found this to be sucessfull...
make defconfig-wifi CROSS_COMPILE=/home/xxx/Downloads/gcc-linaro-arm-linux-gnueabi-2012.04-20120426_linux/bin/arm-linux-gnueabi- ARCH=arm KLIB_BUILD=/home/xxx/Downloads/linux-3.10/ KLIB=/home/xxx/Downloads/rootfs/
make menuconfig CROSS_COMPILE=/home/xxx/Downloads/gcc-linaro-arm-linux-gnueabi-2012.04-20120426_linux/bin/arm-linux-gnueabi- ARCH=arm KLIB_BUILD=/home/xxx/Downloads/linux-3.10/ KLIB=/home/xxx/Downloads/rootfs/
make CROSS_COMPILE=/home/xxx/Downloads/gcc-linaro-arm-linux-gnueabi-2012.04-20120426_linux/bin/arm-linux-gnueabi- ARCH=arm KLIB_BUILD=/home/xxx/Downloads/linux-3.10/ KLIB=/home/xxx/Downloads/rootfs/

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.

Build kernel module for existing binary 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

Resources