0% found this document useful (0 votes)
24 views9 pages

Lab Session 15

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views9 pages

Lab Session 15

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Lab Session: 15 Kernel Modules

Lab session 15: Kernel modules

15.1 Introduction

Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon
demand.
They extend the functionality of the kernel without the need to reboot the system. Custom
codes can be added to Linux kernels via two methods.

The basic way is to add the code to the kernel source tree and recompile the kernel.
A more efficient way is to do this is by adding code to the kernel while it is running. This
process is called loading the module, where module refers to the code that we want to add to
the kernel.

Since we are loading these codes at runtime and they are not part of the official Linux kernel,
these are called loadable kernel module (LKM), which is different from the “base kernel”. Base
kernel is located in /boot directory and is always loaded when we boot our machine whereas
LKMs are loaded after the base kernel is already loaded. Nonetheless, these LKM are very much
part of our kernel and they communicate with base kernel to complete their functions.

LKMs can perform a variety of task, but they come under three main categories,

Device Driver File System Driver System Calls

A monolithic kernel, though faster than a microkernel, has the disadvantage of lack of
modularity and extensibility. On modern monolithic kernels, this has been solved by using
kernel modules. A kernel module (or loadable kernel mode) is an object file that contains
code that can extend the kernel functionality at runtime (it is loaded as needed); When a
kernel module is no longer needed, it can be unloaded. Most of the device drivers are used in
the form of kernel modules.

For the development of Linux device drivers, it is recommended to download the kernel
sources, configure and compile them and then install the compiled version on the test
/development tool machine.

An example of a kernel module

Below is a very simple example of a kernel module. When loading into the kernel, it will
generate the message "Hi". When unloading the kernel module, the "Bye" message will be
generated.
Lab Session: 15 Kernel Modules

Example:

include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_DESCRIPTION("My kernel module");
MODULE_AUTHOR("Me");
MODULE_LICENSE("GPL");
static int dummy_init(void)
{
printk("Hi\n");
return 0;
}
static void dummy_exit(void)
{
printk("By\n");
}
module_init(dum my_init);
module_exit(dummy_exit);
The generated messages will not be displayed on the console but will be saved in a
specially reserved memory area for this, from where they will be extracted by the logging daemon
(syslog). To display kernel messages, you can use the dmesg command or inspect the logs:

# cat /var/log/syslog | tail -2


Feb 20 13:57:38 asgard kernel: Hi
Feb 20 13:57:43 asgard kernel:
Bye # dmesg | tail -2
Hi
By

14.1 Compiling kernel modules

Compiling a kernel module differs from compiling an user program. First, other headers should be
used. Also, the module should not be linked to libraries. And, last but not least, the module must be
compiled with the same options as the kernel in which we load the module. For these reasons, there
is a standard compilation method (kbuild). This method requires the use of two files: a
Makefile and a Kbuild file.
Below is an example of a Makefile:
KDIR = /lib/modules/`uname –r`/build kbuild:
Lab Session: 15 Kernel Modules
make -C $(KDIR) M=`pwd`clean:
make -C $(KDIR) M=`pwd` clean
And the example of a Kbuild file used to compile a module:
EXTRA_CFLAGS = -Wall –g obj-m = modul.o

You can see, calling make on the Makefile file in the example shown will result in the make
invocation in the kernel source directory (/lib/modules/`uname -r`/build) and referring to the
current directory (M = `pwd`). This process ultimately leads to reading the Kbuild file from the
current directory and compiling the module as instructed in this file.

Note
For labs we will configure different KDIR, according to the virtual machine specifications:
KDIR = /home/student/so2/linux
[...]
A Kbuild file contains one or more directives for compiling a kernel module. The easiest
example of such a directive is obj-m = module.o. Following this directive, a kernel module (ko -
kernel object) will be created,

Starting from the module.o file. module.o will be created starting from module.c or module.S.
All of these files can be found in the Kbuild’s directory.

An example of a Kbuild file that uses several sub-modules is shown below:

EXTRA_CFLAGS = -Wall -g

obj-m= supermodule.o
supermodule-y = module-a.o module-b.o

For the example above, the steps to compile are:

compile the module-a.c and module-b.c sources, resulting in module-a.o and module-
b.o objects module-a.o and module-b.o will then be linked in supermodule.o
from supermodule.o will be created supermodule.ko module

The suffix of targets in Kbuild determines how they are used, as follows:

M (modules) is a target for loadable kernel modules


Y (yes) represents a target for object files to be compiled and then linked to a module (
Lab Session: 15 Kernel Modules
$(mode_name)-y) or within the kernel (obj-y)
any other target suffix will be ignored by Kbuild and will not be compiled
Note
These suffixes are used to easily configure the kernel by running the make menuconfig command
or directly editing the .config file. This file sets a series of variables that are used to determine

which features are added to the kernel at build time. For example, when adding BTRFS support
with make menuconfig, add the line CONFIG_BTRFS_FS = y to the .config file. The BTRFS
kbuild contains the line obj-

$(CONFIG_BTRFS_FS):= btrfs.o, which becomes obj-y:= btrfs.o. This will compile the
btrfs.o object and
will be linked to the kernel. Before the variable was set, the line became obj:=btrfs.o and so it

was ignored, and the kernel was build without BTRFS support.

For more details,see the Documentation/kbuild/makefiles.txt and Documentation/kbuild/modules.txt


files within the kernel sources.

14.2 Loading/unloading a kernel module

To load a kernel module, use the insmod utility. This utility receives as a parameter the path to
the *.ko file in which the module was compiled and linked. Unloading the module from the
kernel is done using the rmmod command, which receives the module name as a parameter.

$ insmod module.ko

$ rmmod module.ko

When loading the kernel module, the routine specified as a parameter of the module_init
macro will be
executed. Similarly, when the module is unloaded the routine specified as a parameter of the
module_exit will be executed.

A complete example of compiling and loading/unloading a kernel module is presented below:


Lab Session: 15 Kernel Modules

faust:~/lab-01/modul-lin# ls Kbuild Makefile modul.c


faust:~/lab-01/modul-lin# make
make -C /lib/modules/`uname -r`/build M=`pwd` make[1]: Entering directory `/usr/src/linux-
2.6.28.4'
LD /root/lab-01/modul-lin/built-in.o CC [M] /root/lab-01/modul- lin/modul.o Building
modules, stage
MODPOST 1 modules CC /root/lab-01/modul-
lin/modul.mod.o LD [M] /root/lab-01/modul-lin/modul.ko
make[1]: Leaving directory `/usr/src/linux-2.6.28.4'
faust:~/lab-01/modul-lin# ls

built-in.o Kbuild Makefile modul.c Module.markers

modules.order Module.symvers modul.ko modul.mod.c

Information about modules loaded into the kernel can be found using the lsmod command or by
inspecting the /proc/modules, /sys/module directories.
modul.mod.o modul.o

faust:~/lab-01/modul-lin# insmod modul.ko

faust:~/lab-01/modul-lin# dmesg | tail -1 Hi

faust:~/lab-01/modul-lin# rmmod modul

faust:~/lab-01/modul-lin# dmesg | tail -2 Hi


Bye

14.3 Debugging

Troubleshooting a kernel module is much more complicated than debugging a regular program.
First, a mistake in a kernel module can lead to blocking the entire system. Troubleshooting is
therefore much slowed down. To avoid reboot, it is recommended to use a virtual machine
(qemu, virtualbox, vmware).

When a module containing bugs is inserted into the kernel, it will eventually generate a kernel
oops. A kernel oops is an invalid operation detected by the kernel and can only be generated by
the kernel. For a stable kernel version, it almost certainly means that the module contains a bug.
After the oops appears, the kernel will continue to work.

Very important to the appearance of a kernel oops is saving the generated message. As noted
Lab Session: 15 Kernel Modules
above, messages generated by the kernel are saved in logs and can be displayed with
the dmesg command. To make sure that no kernel message is lost, it is recommended to
insert/test
the kernel directly from the console, or periodically check the kernel messages. Noteworthy is
that an oops can occur because of a programming error, but also a because of hardware error.

If a fatal error occurs, after which the system cannot return to a stable state, a kernel panic is
generated.

Look at the kernel module below that contains a bug that generates an oops:

/*
* Oops generating kernel
module */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

MODULE_DESCRIPTION (“Oops”);
MODULE_LICENSE (“GPL”);
MODULE_AUTHOR (“PSO”);

Minicom:

Minicom (or other equivalent utilities, eg picocom, screen) is a utility that can be used to connect
and interact with a serial port. The serial port is the basic method for analyzing kernel messages
or interacting with an embedded system in the development phase. There are two more common
ways to connect:

a serial port where the device we are going to use is /dev/ttyS0


a serial USB port (FTDI) in which case the device we are going to use is /dev/ttyUSB.

For the virtual machine used in the lab, the device that we need to use is displayed after the
virtual machine starts:

char device redirected to /dev/pts/20 (label virtiocon0)

Minicom use:
Lab Session: 15 Kernel Modules

#for connecting via COM1 and using a speed of 115,200 characters per
second minicom –b 115200 –D /dev/ttyS0

#For USB serial port connection


minicom –D /dev/ttyUSB0

#To connect to the serial port of the virtual machine


minicom –D /dev/pts/20

14.4 Manage kernel modules and their parameters

You have been asked to enable connection tracking timeflow stamping in the Linux kernel of a
particular host. This change should take effect immediately, as well as persist upon reboot.

The kernel module to change is nf_conntrack, you need to modify the parameter that enables
time stamping.

Start by logging in to the lab servers using the credentials provided on the hands-on lab page:

ssh cloud_user@PUBLIC_IP_ADDRESS

Become the root user:

sudo su -

Enable nf_conntrack time stamping in the running kernel

Check to see if the module is loaded:

lsmod | grep nf_conntrack

View the parameters available for the nf_conntrack module:

modinfo nf_conntrack

Verify the current setting of the timestamp parameter:

cat /sys/module/nf_conntrack/parameters/tstamp

Stop the firewall and unload the module:


systemctl stop firewalld
modprobe -r nf_conntrack
Load the module with timestamping enabled:
Lab Session: 15 Kernel Modules
modprobe nf_conntrack tstamp=1

Verify the current setting of the timestamp parameter:

cat /sys/module/nf_conntrack/parameters/tstamp

Make the change persist through a restart

Make the change persist through a reboot:

Echo &quot; options nf_conntrack tstamp=1&quot; &gt; /etc/modprobe.d/nf_conntrack.conf


Lab Session: 15 Kernel Modules

LAB EXERCISE:

Q1.What is debugging?

Q2.What is minicom and why it is used?

Q3.Write a program to compiling and loading/unloading a kernel module.

Q4.What advantage do LKMs offer?

Q5.Explain the following command

a) Mod probe -r nf_conntrack

b) Mod probe

nf_conntrack

tstamp=1

c) Sudo su

You might also like