Lab Manual 06 Kernel Modules PDF
Lab Manual 06 Kernel Modules PDF
Contents
Objective..................................................................................................................................... 2
Kernel Modules ........................................................................................................................... 2
Why We Need Kernel Modules? ................................................................................................. 2
List of Currently Loaded Modules ............................................................................................... 2
Command to Insert or Remove Modules ..................................................................................... 2
Writing Kernel Modules ............................................................................................................... 3
Writing Your First Module and Insert it to the Kernel ................................................................ 3
With module_init() & module_exit() i.e. Init Macros .................................................................. 5
With Licensing and Documentation ......................................................................................... 5
printk() ........................................................................................................................................ 7
Module Parameters .................................................................................................................... 7
Modifying Parameter Value ......................................................................................................... 9
Implementation of Kernel Threads .............................................................................................10
Lab Task: ...................................................................................................................................11
Objective
The objective of this lab is to demonstrate how to compile, load, list and remove modules from/to
kernel and introduce module parameters i.e. how to add parameter in you module, adding
parameter to your modules, types of parameter and setting parameter from outside kernel
module. To introduce kernel symbol table and /proc file system.
Kernel Modules
“Modules are pieces of code that can be loaded and unloaded into the kernel upon demand.”
Linux kernel modules are shared object files with extension ‘.o’ (for kernel version 2.4 or lower)
or ‘.ko’ (for new kernel version). They are chunk of kernel code and they compiled separately.
They can be removed or inserted at any time. They extend the functionality of the kernel without
the need to reboot the system. For example, one type of module is the device driver, which
allows the kernel to access hardware connected to the system.
Let’s Google:
modprobe does the similar work like insmod. What is the difference between two??
Writing Kernel Modules
Writing Your First Module and Insert it to the Kernel
Before we begin, lets first go come back as a root user as we will work inside kernel mode and
normal users are not permitted to play with it! Type the below commands to create directories
and files.
~/$ sudo -i
~/$ mkdir /hello
~/$ cd /hello
/hello$ touch hello.c ; touch Makefile
Now that are directory and files are created, we need to put content in it.
Copy this content into the ‘hello.c’ file
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void) {
printk(KERN_INFO "hello [INFO] Hellow World! \n");
/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}
void cleanup_module(void) {
printk(KERN_INFO " hello [INFO] Goodbye World! \n ");
}
Points to Ponder:
Kernel modules must have at least two functions:
"start" (initialization) function called init_module() which is called when the module is
insmoded into the kernel
"end" (cleanup) function called cleanup_module() which is called just before it is
rmmoded.
Typically, init_module() either registers a handler for something with the kernel, or it replaces
one of the kernel functions with its own code (usually code to do something and then call the
original function). The cleanup_module() function is supposed to undo whatever init_module()
did, so the module can be unloaded safely.
Now we insert the compiled module to the kernel module’s list so that it starts executing
To verify that our module is added to the list, we can do this by using the following command
To see that the output from our module run ‘dmesg | tail -1’
“dmesg - print or control the kernel ring buffer”
You can see that init_module function is called however, cleanup_module is called when you
remove your module, hence init_module function will setup the module which may call a function
that will run forever in a while loop and cleanup_module is called to terminate that function and
to stop the execution of the module. To remove the module from the list, use the following
command.
module_init(hello_2_init);
module_exit(hello_2_exit);
In kernel 2.4 and later, a mechanism was devised to identify code licensed under the GPL so
people can be warned that the code is non open-source. This is accomplished by the
MODULE_LICENSE() macro. By setting the license to GPL, you can keep the warning from
being printed. This license mechanism is defined and documented in ‘linux/module.h.
/*
Get rid of taint message by declaring code as GPL.
*/
MODULE_LICENSE("GPL");
/*
Or with defines, like this:
*/
MODULE_AUTHOR(DRIVER_AUTHOR); /* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC); /* What does this module do */
/*
This module uses /dev/testdevice. The MODULE_SUPPORTED_DEVICE macro might be
used in the future to help automatic configuration of modules, but is currently unused other
than for documentation purposes.
*/
MODULE_SUPPORTED_DEVICE("testdevice");
The above code is written on a file name ‘hello-3.c’ and the Makefile modified as previous.
Now compile and run the following command
/hello$ modinfo hello-3.ko
The above command would get the following output
printk()
Module Parameters
Previously, we studied modules without parameters that have a static output and no user or time
interaction. These modules are no good since they have a very limited functionality. Modules
are just like functions that need parameters i.e. user input to produce variation in their outputs.
Addition of variables to a module is a bit tricky, since now we are working in kernel space and we
don’t have access to the screen so there is no direct way to get user inputs for our modules. What
we do is to make our parameters static so that they could stand outside the module, and we could
address them from there.
Well, there are three types of symbols according to their visibility scope:
1) STATIC: visible only in their source file
2) EXTERNAL: visible only for built – in kernel source code
3) EXPORTED: visible for apparently all loadable kernel modules
After addition of some parameters your module code looks like the following:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
EXPORT_SYMBOL(mod7_exported_param);
MODULE_AUTHOR("ABC");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("symbols exported and otherwise...");
One more thing that although sounds a bit weird about the modules is that by themselves,
modules never know that they have any parameter, so they don’t expect any output from
outside the module that is command line. So you need to explicitly tell a module that it does
have a parameter named this, and of type this with these user rights outside you (module). You
can do this by:
as written in comments in above code. The user rights have the octal value representing owner,
group and others, prefixed by a zero. The reason that the line is commented out is that the very
next line to code does exactly the same job with an extension.
If you know that your variable will be listed and used among those thousands of kernel’s variables,
you need to use some way to make it look unique in the list for the sake of identification. So
preferably you would use something like myMod_var_int to make it stand out of the crowd, sounds
good, but… using this long name for a variable that is redundant in your code may lead to frequent
mistakes in writing the variable name, resulting in long list of errors when you would run “make”.
The solution to this is, there should be some way that you could use a smaller alias of the variable
name in module during programming and use a longer more expressive or descriptive name for
addressing it from outside, this is exactly what module_param_named does. It renames the
variable to a new name that is visible to outside world letting you use your short less descriptive
name inside. The syntax is similar except for that the list of parameters to this function also
includes the new name of the variable.
There are two exported kernel symbols that we are using in our module. First one is jiffies which
is defined in jiffies.h representing cpu instruction logical timer value, and the other is the function
printk() which we are using for output in log file.
Remember two things can be exported, variables and functions and these are jointly referred to
as symbols in Kernel programming terms.
This is the simplest and least flexible method among the three that is you initialize
variables at the time you declare them. This value is constant and persists till end if
neither changed by program itself nor modified from outside.
2- Set a value at the time of module insertion
In this method you simply write the assignment statement right after insmod
module_name.ko as shown in following
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/kthread.h>
#include<linux/sched.h>
#include<linux/time.h>
#include<linux/timer.h>