Wednesday, March 23, 2011

Overview of compiling Kernel Modules

Here is look in the steps involved in compilation of a kernel module, the journey from the .c file to the .ko .

The makefile that is used to build kernel module generally looks a follows.



*******************************makefile*****************************************

ifneq ($(KERNELRELEASE),)
   obj-m := modulename.o
else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 
endif

***********************************************************************************
The 2.6 kernels use a kbuild system to build the kernel modules and to compile an external module also the same has to be used. Hence in the makefile that we write we will have to use the makefile that is present in the kernel source tree.

Two passes are made of the above makefile, in the first pass we call make from the command line. As we are not sure about the location of the kernel source  tree location the first "if" condition turns out to be false and in the else part we set the KERNELDIR to the path to the makefile of the kernel which is by default present in the location /lib/modules/"kernel version"/build.
and then call make again.
note :  uname -r retunrs the kernel version.

The default target gets called if we do not mention any target in the command line.
Here we call make again, but with  the option -C to tell "make" to use the makefile present in the directory being passed as argument after -C, which is the path to kernel makefile.
The M option tells the kernel makefile that we are building external kernel modules and the same are present at the location passed as an absolute path after "M". 
The target "modules" is passed to mean that modules located in the currnet directory have to be compiled. The default working is also the same and hence should work even if it is not passed.

The second pass of the makefile is done by the kbuild system which reads only the assignment of "obj-m := modulename.o"  from the makefile.

Now the kbuild system know that it has to build "modulename.ko" and will look for "modulename.c" or "modulename.S" for the source. In case these files are not persent in the directory passed to "M" , the compiling will stop with an error.

If the files are present the source file is compiled to a "modulname.o",  and "modulename.mod.c" is created which is compiled to "modulename.mod.o".
The modulename.mod.c is a file that basically contains the information about the module (Version information etc).
The modulename.o and the modulename.mod.o are linked together by modpost in the next stage to create the "modulename.ko" .

A few other files that get created are
"module.symvers": This will contain any of external symbols that is defined in your module and hence not present in the module.symvers of the kernel .

"modules.order" : In case you are compiling multiple modules together, it will list out the order in which the compilation and creation of .ko takes

"module.markers" : This lists out all the markers placed in the your module code. A marker placed in code provides a hook to call a function (probe)   that you can provide at runtime

1 comments:

Unknown said...

Kernel modules need to be compiled a bit differently from regular userspace
more details visit: write my paper

Post a Comment