This tutorial provides a guide for using Linux Kernel modules. We just cover basic issues, such as load and unload of modules.
If you did not read this tutorial yet, skip this section. I added this section as a summary for someone that already read this tutorial and just want to remember a specific command.
make modules make M=drivers/<TARGET_DRIVER> sudo make modules_install modinfo <DRIVER_NAME> lsmod | grep <DRIVER_NAME> dmesg -H sudo modprobe <TARGET_DRIVER> sudo modprobe -r <TARGET_DRIVER> modprobe --show-depends <module>
During my first attempts to start working with Linux Kernel, I read many books and tutorials about device drivers. Although most of them had examples of compiling an external module, some things were still not so clear to me. I was a newcomer, and I felt that I needed to have a deep understanding on how to compile and install in-tree modules in order to start working with kernel drivers.
How can I compile a single in-tree module? How can I install it? Doubts still lingered in my mind…
I confess that I had a difficult time achieving this task for the first time; it took me half a day to learn the essential steps. Nowadays, I see that this is a simple task; however, I want to shed some light on this issue to help newcomers.
For this tutorial, I decided to work with a module named IIO dummy
drivers/iio/dummy ) because we can
conduct some experiments with that in future tutorials. Please note that the
steps and tips described here apply easily to other modules.
Some of the operations described here requires
sudo. If you are not 100%
comfortable with Linux system or you are a newcomer, I strongly advise you to
start working inside a virtual machine; you can read more about this here:
Use Qemu to play with Linux Kernel.
Compile In-tree Module
When we start to work with in-tree drivers, we want to spread some
pr_info  around the code and make other small
changes to find a way to understand the code. In this sense, every time that we
make a change, we can compile the modules with the following command:
The above command works pretty well, and I still use it in the present day.
Note that only
make works, too. Sometimes, we just want to compile and clean
a single module. To do this, we can use the following command:
M expects a path to the target driver. This allows you to
compile and clean a target module without touching other drivers. For example,
make M=drivers/iio/dummy clean
There is a small trick to use this command correctly: your module must be enabled in the .config
file, and your kernel should be compiled with this option before you use
If you don’t know how to do it, take a look at
Install In-tree Module
Before introducing you to the module installation method, it is worth to elaborate a little about loadable modules in a Linux file system. First of all, try the commands below:
$ uname -r 4.9.0-8-amd64 $ ls /lib/modules 4.9.0-6-amd64 4.9.0-7-amd64 4.9.0-8-amd64
uname -r print the kernel release and the
directory stores all modules .
It is important to notice that in
/lib/modules/ each version of kernel
compiled for your system has its directory; from the practical point of view if
you install a new module, you can check it in here.
For installing the module, I use the command:
sudo make modules_install
If you are working in a module and for any reason, you decide to install a
modified version of it, you should take a careful look at (1)
uname -r, and (3) the current kernel version that you are working on. A
common mistake is installing modules from the latest kernel version without
update the kernel image.
Load and unload
GNU/Linux can dynamically load kernel modules; from the user perspective, users can load modules during the execution time. There’s a different way to load and unload modules, and we will briefly describe it in this section.
When I started to play with modules, I tried to work with
command. But since I had just begun to work with drivers, these
commands made the whole experience really painful because they are easy to misuse, as a consequence, may lead to a kernel panic. After long hours of reading and debugging, I understood why people
always recommend the command
modprobe. To understand how module loading works,
keep in mind that all drivers installed in the system can be found at
/lib/modules/$(uname -r). Also, it is essential to know that
command is a wrapper for
rmmod. By the way, the reason why the command
modprobe makes it easier to load and unload modules is because it handles
dependencies for you and avoids kernel problems.
Ok, let’s try to load the module with the following command:
sudo modprobe iio_dummy
Besides analyzing the output from
modprobe, you can also verify if everything
worked correctly with the command
lsmod | grep <TARGET_MODULE> or by taking a look at
the end of the
dmesg log. Try:
lsmod | grep iio_dummy dmesg -H
If you want to remove a modules, you can try:
sudo modprobe -r iio_dummy
Compile Kernel Module Outside from In-Tree
It is possible to develop a driver as a separate project from the Kernel. In
this tutorial, we are only interested in how to load and unload modules; in
this sense, I want to introduce commands
download a simple module at:
Extract the project file with:
tar -xaf simple_dd.tar.gz
Compile the module with:
cd simple_dd make
To test this module, it would be nice for you to open two terminals side by
side. In a terminal, just type
dmesg -wH and, in the other, type:
sudo insmod hello_world.ko sudo rmmod hello_world
Tips and Troubleshooting
Here I want to add some tips and troubleshoots briefly. I will probably update this section in the future. If you have any helpful advice to improve this section, please mail it to me.
Check Installed Module
Sometimes, I do not feel confident that my module has been loaded correctly;
because of this, I like to add some prints or make a simple change in the code.
The most straightforward approach to check if your module was correctly loaded
in the system is changing the
MODULE_DESCRIPTION macro and check the metadata
with the command modinfo. For example, change the line
any driver that you use with something like that:
MODULE_DESCRIPTION("YEP... I LOADED THE CORRECT DRIVER");
Then install and load the module again; after that, you can check the
description with the
modinfo command. For example:
$ modinfo iio_dummy filename: /lib/modules/4.16.0-rc3-TORVALDS+/kernel/drivers/iio/dummy/iio_dummy.ko.xz license: GPL v2 description: YEP... I LOADED THE CORRECT DRIVER author: Jonathan Cameron <email@example.com> srcversion: 1C4C5F875A87E3DFD4F2820 depends: industrialio-sw-device,industrialio,iio_dummy_evgen,kfifo_buf retpoline: Y name: iio_dummy vermagic: 4.16.0-rc3-TORVALDS+ SMP preempt mod_unload modversions
modinfo collects information from the Linux kernel modules
directory . This is really useful, to
help you to figure out if your module is correctly loaded. A common mistake is
to compile the module with a different kernel target, this produces errors such
FATAL: Module drivers/<path> not found in directory /lib/modules/<kernel_version>
If you get this error, the tip above can help you to figure out what is wrong. Lastly, remember to verify the kernel Makefile to be sure about your kernel version or your distro version.
Get Dependencies Information
Sometimes, it is important to know the modules dependencies. You can use the following command:
$ modprobe --show-depends <module>
Why is this important? If you try something really radical as
rmmod -f, it is
a good idea to know the exact dependencies related to your device.
From my experience, it is not a good idea to use
rmmod -f with large modules.
It is ok, if the module is small or if you make it. If you really know what you
are doing, use it; if not, avoid. Prefer
I would like to thanks Melissa Wen for her detailed review. I really appreciate you taking the time out to share your feedback.
- V1: Release
 “IIO dummy source code”. URL: https://github.com/torvalds/linux/tree/master/drivers/iio/dummy. ⤴
 Jonathan Corbet. “The perils of pr_info()”. (2012/03/21) URL: https://lwn.net/Articles/487437/. ⤴
 Rodrigo Siqueira. “Kernel Compilation and Installation”. (2019/02/16) URL: https://flusp.ime.usp.br/kernel/2019/02/16/Kernel-compilation-and-installation/. ⤴
 “Linux kernel modules”. URL: http://linux-training.be/sysadmin/ch28.html#idp68121456. ⤴
 Computer Hope. “Linux modinfo command”. (07/12/2017) URL: https://www.computerhope.com/unix/modinfo.htm. ⤴
comments powered by Disqus