This presentation gives introduction to kernel module programming with sample kernel module.
It helps to start with kernel programming and how it can be used to develop various types of device drivers.
Introduction to kernel modules
• Understanding Kernel modules
• Writing a simple kernel module
• Compiling the kernel module
• Loading and unloading of modules
• Kernel log
• Module dependencies
• Modules vs Programs
Linux kernel has the ability to extend at runtime the set of features
offered by the kernel.
This means that you can add functionality to the kernel while the system
is up and running.
Modules are pieces of code that can be loaded and unloaded into the
kernel upon demand.
For example, one type of module is the device driver, which allows the
kernel to access hardware connected to the system.
Without modules, we would have to build monolithic kernels and add
new functionality directly into the kernel image.
Besides having larger kernels, this has the disadvantage of requiring us to
rebuild and reboot the kernel every time we want new functionality.
• Gets information about the module: parameters, license, descriptions
• Load the given module. Full path of module is needed
• Unloads the given module
• Displays the list of modules loaded.
• Check /proc/modules file
• Loads the kernel modules plus any module dependencies
Write simple module
static int __init hello_init(void)
printk(“Hello :This is my first kernel modulen");
static void __exit hello_exit(void)
printk(“Bye, unloading the modulen");
MODULE_DESCRIPTION(“Sample module"); MODULE_AUTHOR(Vandana Salve");
Headers specific to the linux kernel <linux/xxx.h>
• No access to the usual C library
An initialization function
• Called when the module is loaded using insmod/modprobe tool
• Perform all the initialization functionality
• Returns an error code
• 0- success
• negative value on failure, errors defined in header file
• Declared by the module_init() macro
A cleanup function
• Called when the module is unloaded using rmmod tool
• Perform all the cleanup functionality
• Declared by the module_exit() macro.
• Add description about the kernel module
• Add the information about the author of the module
– MODULE LICENSE
• Add license for example GPL
Compiling a module
Kernel modules need to be compiled a bit differently from regular user
To learn more on how to compile modules which are not part of the
official kernel, see file linux/Documentation/kbuild/modules.txt.
Option1: Inside the kernel tree
– Well integrated into the kernel configuration/compilation process.
– Driver can be build statistically if needed
Option 2: Out of tree
– When the code is outside of the kernel source tree, in a different
• Easier to handle than modifications to the kernel itself.
• Not integrated to the kernel configuration/compilation process,
needs to be build separately
• driver cannot be built statistically if needed.
Compiling an out-of-tree module
When the kernel module code is
outside of the kernel source tree,
i.e. in a different directory.
Makefile for basic kernel module
KDIR := /path/to/kernel/sources
obj-m := hello.o
make -C $(KDIR) M=$(PWD) modules
make –C $(KDIR) M=$(PWD) clean
• Refer Documentation/kbuild/modules.txt for details
Overview of make & makefiles
The “make” program automates the building of software based on
specification of dependencies among the files.
“make” determines which pieces of a large program need to be
recompiled and issue commands to recompile them.
To use make, you must write a file called makefile.
A makefile is simple a way of associating short names, called ‘targets’,
with a series of commands to execute when the action is requested.
– Target clean, performs actions that clean up after the compilation—
removing object files and resulting executable.
– Target all, performs action that compile the filesv
When a new module is loaded, related information is available in the
– The kernel keeps its messages in a circular buffer.
– Kernel log messages are available through the ‘dmesg’ command
– Kernel log messages can be seen in /var/log/messages and/or
Some kernel module can depend on other modules, which need to be
Dependencies are described in
This file is generated when you run make modules_install
sudo modprobe <module_name>
– Loads all the modules the given module depends on. Modprobe looks
into /lib/modules/<kernel-version> for the object file corresponding
to the given module
Sudo modprobe –r <module_name>
– Remove the module and all dependent modules, which are no longer
Applications Vs. Kernel modules
• Performs single task from
beginning to end
• Application can call functions,
which it doesn’t define. The
linking stage resolves the external
references loading the
appropriate libraries. E.g libc for
• Module registers itself to serve
the future request and its ‘main’
function terminates on loading.
• The module is linked only to the
kernel and it can only the
functions that are exported by
• No C library is linked with the
Functions available to modules
In the hello world example, you might have noticed that we used a
function, printk() but didn't include a standard I/O library.
That's because modules are object files whose symbols get resolved upon
The definition for the symbols comes from the kernel itself; the only
external functions you can use are the ones provided by the kernel.
If you're curious about what symbols have been exported by your kernel,
take a look at /proc/kallsyms.
Passing command line arguments
Modules can take command line arguments, but not with the argc/argv
you might be used to.
To allow arguments to be passed to your module, declare the variables
that will take the values of the command line arguments as global and
then use the module_param() macro, to set the mechanism up.
At runtime, insmod will fill the variables with any command line
arguments that are given
$insmod hello_2.ko int_param=50
The variable declarations and macros should be placed at the beginning of
the module for clarity.
The module_param() macro takes 3 arguments:
– the name of the variable,
– its type and permissions for the corresponding file in sysfs.
– Integer types can be signed as usual or unsigned.
If you'd like to use arrays of integers or strings see
– module_param_array() and
Advantages of modules
Modules make it easy to develop drivers without rebooting: load, test,
unload, rebuild & again load and so on.
Useful to keep the kernel size to the minimum (essential in embedded
systems). Without modules , would need to build monolithic kernel and
add new functionality directly into the kernel image.
Also useful to reduce boot time, you don’t need to spend time initializing
device that may not be needed at boot time.
Once loaded, modules have full control and privileges in the system.
That’s why only the root user can load and unload the modules.
Usage of modules
Character device drivers
Block device drivers
Network device drivers
Any type of device drivers handling the different types of devices such as
USB, I2C etc. etc.
Kernel modules can be used to implement any functionality needed
runtime on demand