How to build kernel module without full kernel source tree? - linux

I would like to build kernel module without kernel source tree.
Instead that, I specified the kernel header directory only.
This reference link tell me it should be workable :
build kernel module w/o source source tree
But some other reference links tell me should build module with full kernel source tree!
My question is :
1. Shall I build kernel module link with full kernel source tree ?
2. Is it necessary to do a full build under kernel source tree before build my single module ?

Not it's not necessary. You need a header files that contains function and types declarations. You also kernel tree with Makefiles and Kconfig but without sources. This kernel tree is needed by kbuild - kernel building system.
Absolutely not. You can build a single module without building whole kernel regardless of it's out-of-tree or in-tree module.

No to both questions. You're talking about out-of-tree (or "external") modules.
Here is a tutorial of Building External Modules.
And here is a simple sample of a Makefile.
obj-m += your-module.o
KDIR=/lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules

Related

Linux Kernel : Building Out-of-tree module for kernel , but no linux-headers in apt-cache search

I am working on linux kernel development, and was trying to make my own modules for testing purposes. However, for the latest kernel source codes, the linux-headers don't exist. It only exists for 4.9.0-7 .
I googled and found 1 method where we make the module against the kernel source tree that we want (eg. 4.18)
make -C /home/prasad/linux-4.18/ M=$(PWD)
which does generate the .ko for my module. However, when I load up my kernel and insmod it , it says
insmod: ERROR: could not insert module test.ko: Unknown symbol in module
So how exactly do I generate a .ko file from my host machine that can be inserted for the 4.18 kernel ?
PS: My doubt is not a duplicate as I cannot "install" the 4.18 kernel in my vm, Im trying to avoid doing that. My question is more specific to generating an insertable .ko module, and not finding any other way to insert it in 4.18.
You cant use a module built for 4.18 in a 4.9 kernel.
If the headers for the kernel version you are building for are not available via apt/yum/etc, you will need to download the source manually from: https://www.kernel.org/
In the makefile for your module, you will specify the path to the kernel source code that you have downloaded and extracted.
That should allow you to build the module for the desired kernel version.

Intel Galileo adding kernel header files to the cross compile toolchain

im on BSP v1.1
yocto is 1.6
I'm trying to set up the cross compile toolchain to compile character driver code
but the output i get is
[mark#localhost ~]$ ${CC} first.c -o first
first.c:1:24: fatal error: linux/init.h: No such file or directory
.#include
^ compilation terminated.
I think the issue is that
the header is not in the toolchain
/opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/include/linux/~
there is no at this location
I think something has to be added as IMAGE_INSTALL or IMAGE_FEATURE but i dont know what
am I on the right track ?
does anyone know what i have to add ?
or am i completely off tracks altogether?
Well, first and foremost, you can never build a kernel module by just running ${CC} on it. You should always use a Makefile, which redirects most of its work to the kernel source Makefil.
Create a Makefile for you module, consisting of something similar to:
obj-m += hello-1.o
all:
make -C $(KERNEL_SRC M=$(PWD) modules
clean:
make -C $(KERNEL_SRC) M=$(PWD) clean
Example taken from The Linux Kernel Module Programming Guide (Note that the actual commands needs to have a tab character for indentation).
Then you'll have to define KERNEL_SRC to be /opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel/, either in the Makefile, or from your make call. (Using a variable like KERNEL_SRC will ensure that your module recipe automatically picks the right location when building using bitbake).
To manually build your kernel module:
Source the environment-* file for your SDK.
Go to you modules directory.
KERNEL_SRC=/opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel LDFLAGS="" make
However, this will fail, as fixdep can't be found. We'll fix this manually.
cd /opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel
make silentoldconfig scripts
Go back to your modules directory.
KERNEL_SRC=/opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel LDFLAGS="" make
This should now produce hello.ko which you should be able to insmod on the Galileo board.

What happens behind the scenes when we build loadable kernel modules

I have built few kernel modules before and I followed the steps to generate the .ko files to insmod.
I write a Makefile which has
obj-m := filename.o
and execute the command from shell
# make -C /lib/modules/$(uname -r)/build M=`pwd` modules
This command generates the filename.ko, filename.mod, filename.o, filename.mod.o.
Some google search showed that /lib/modules/$()/build is a symbolic link to my kernel source tree.
and M=pwd is my source file directory.
But what happens when just this small piece of command executes to generate my .ko kernel object file. Where, which directories, or binaries, utilities will the make command use.
PS: ( the filename.ko file would be generated by some compilation magic using filename.o and filename.mod.o ).
Thank you.

Driver/module cross compilation

I am trying to cross compile a driver for an arm based board. In the make file the search path for include files is that of the host machine's kernel i.e it points to the linux headers that come with ubuntu.
I also have the kernel source tree of target board present on the host system(i7/ubuntu).
My Question is that which include path is needed for cross compilation (native system's linux headers path or the path to the kernel source tree of board ?
Does same thing applies to all modules including drivers?
Here is a Makefile for an out of tree driver. The architecture, toolchain and kernel dir specified :
ifneq ($(KERNELRELEASE),)
# We were called by kbuild
obj-m += fpgacam.o
else # We were called from command line
KDIR := path/to/your/target/kernel
PWD := $(shell pwd)
CROSS=arm-none-linux-gnueabi-
default:
#echo ' Building Cam drivers for 2.6 kernel.'
#echo ' PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS) modules
install:
./do_install.sh *.ko
endif # End kbuild check
######################### Version independent targets ##########################
clean:
rm -f -r *.o *.ko .*cmd .tmp* core *.i
When make is called from the module directory, the command line path is taken, and make is redirected to the kernel directory build system using make -C. The kernel build system then the different variable passed to it to go back into the module directory with everything setup (include path, toolchain etc ..) to compile a module. This second time through the Makefile, the kbuild path is taken, and the module is built as if it was in-tree.
Compiling with your build-system's headers is spectacularly bad news, and may subtle binary incompatibilities that manifest themselves as seemingly bizarre crashes on the target.
As you've already discovered, the kernel is already hardened against this and will refuse to load modules built against the wrong headers. You'll need to build using the same source tree as the existing kernel - including any patches. You might as well at this point rebuild the entire kernel.
The kernel tree is self-contained, so simply cross-compiling it in place will work. If you're adding a driver it's probably easiest to compile it in-tree.
If you want to build any user-space components, you have two solutions:
Pass the --sysroot=<dir> option to gcc, where <dir> is the system root of your target system
Build gcc and binutils to use as their default sysroot
The latter approach is the one that Angstrom uses, and it save a lot of butt-hurt.
You might want to try using crosstool-ng
It takes care of the majority of the work. You only need to bother about the configuration settings you want to enable for kernel compilation.
Here another reference: link

What does this make command do?

make -C $(KERNEL_DIR) SUBDIRS=pwd` modules
Can someone elaborate this?
The -C means "change to this directory before starting make." The SUBDIRS is a variable used by the Linux kernel make system. SUBDIRS=`pwd` means that the kernel makefiles should look in the current directory, because pwd means "print working directory." And modules means to make modules.
It probably uses the kernel make system to build an out-of-tree module. Out-of-tree means a kernel module that is not shipped with the kernel.
In fact, I seem to recall seeing this command used as part of the Nvidia binary module installer.

Resources