Linux Kernel Development
Enable Javascript to display Table of Contents.
Creating Out-Of-Tree Modules
Preparation
Before compiling an out-of-tree module you have to
- download, configure and build the Kernel or
- install a package of your distribution to provide the files and configuraiton (e.g. linux-headers-generic)
- download and configure the Kernel and run
make modules_prepare
.
Makefile
When the whole module consists of one single source file (e.g. foo.c
) the following line written in the file Kbuild
will create the module foo.ko
:
obj-m := foo.o
When additional files shall be compiled and linked they have to be added in the next line(s):
obj-m := foo.o
foo-y := bar.o jup.o zup.o yo.o
Finally it would be a good idea, to write a wrapper Makefile
so that the code can be compiled by a single call of make
without arguments:
KDIR ?= /lib/modules/$$(uname -r)/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
Finally you can also merge both files into one single Makefile
- the INSTALL_MOD_DIR
defines in which folder the module will be installed:
INSTALL_MOD_DIR=gandalf
ifneq ($(KERNELRELEASE),)
obj-m := foo.o
foo-y := bar.o jup.o zup.o yo.o
else
KDIR ?= /lib/modules/$$(uname -r)/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
endif
Further information about Makefiles
in the Linux Kernel can be found here.
Module
For creating a module this can be used as a starting point:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static char pps_dev_name[sizeof("ppsNNN\0")];
module_param_string(pps_dev_name, pps_dev_name, ARRAY_SIZE(pps_dev_name), S_IRUGO);
MODULE_PARM_DESC(pps_dev_name, "Name of pps device of pps_ast driver, e.g. pps7 for /dev/pps7");
static int __init foo_init(void) {
printk(KERN_INFO "foo started...\n");
strlcpy(pps_dev_name, "n/a", ARRAY_SIZE(pps_dev_name));
return 0;
}
static void __exit foo_exit(void) {
printk(KERN_INFO "foo stopped!\n");
}
module_init(foo_init);
module_exit(foo_exit);
MODULE_AUTHOR("My Name");
MODULE_DESCRIPTION("Some text describing the module");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
Building
In a first step you have to define the location of your (prebuilt) Kernel:
# when building for the running kernel (e.g. of your distribution)
$ export KDIR=/lib/modules/$(uname -r)/build
# when building for another kernel (e.g. of Yocto)
$ export KDIR=<path-to-your-kernel-folder>
If this is done, you can compile your module. If it has only a Kbuild
file (and no Makefile
convenience wrapper) you need the full command:
# building only single files of the module
$ make -C $KDIR M=$PWD foo.lst bar.o
# building the whole module
$ make -C $KDIR M=$PWD
# installing the module
$ make -C $KDIR M=$PWD modules_install
# cleaning the module
$ make -C $KDIR M=$PWD clean
If you have created the convenience Makefile
a simple make
is enough:
$ make
Source: https://www.kernel.org/doc/Documentation/kbuild/modules.txt