Kernel Modules

What is a kernel module?

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.

If you want to add code to a Linux kernel, the most basic way to do that is to add some source files to the kernel source tree and recompile the kernel. In fact, the kernel configuration process consists mainly of choosing which files to include in the kernel to be compiled.

But you can also add code to the Linux kernel while it is running. A chunk of code that you add in this way is called a loadable kernel module. These modules can do lots of things, but they typically are one of three things: 1) device drivers; 2) filesystem drivers; 3) system calls. The kernel isolates certain functions, including these, especially well so they don’t have to be intricately wired into the rest of the kernel.

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.

Loadable Kernel Module [LKM]

Loadable kernel modules are often called just kernel modules or just modules, but those are rather misleading terms because there are lots of kinds of modules in the world and various pieces built into the base kernel can easily be called modules. We use the term loadable kernel module or LKM for the particular kinds of modules this post is about.

Some people think of LKMs as outside of the kernel. They speak of LKMs communicating with the kernel. This is a mistake; LKMs (when loaded) are very much part of the kernel. The correct term for the part of the kernel that is bound into the image that you boot, i.e. all of the kernel except the LKMs, is “base kernel.” LKMs communicate with the base kernel.

In some other operating systems, the equivalent of a Linux LKM is called a “kernel extension.”

What is “Linux”? Well, first of all, the name is used for two entirely different things, and only one of them is really relevant here:

  1. The kernel and related items distributed as a package by Linus Torvalds.
  2. A class of operating systems that traditionally are based on the Linux kernel.

Only the first of these is really useful in discussing LKMs. But even choosing this definition, people are often confused when it comes to LKMs.

LKMs did not exist in Linux in the beginning. Anything we use as LKM for today was built into the base kernel at kernel build time instead. LKMs have been around at least since Linux 1.2 (1995).

Device drivers and such were always quite modular, though. When LKMs were invented, only a small amount of work was needed on these modules to make them buildable as LKMs. However, it had to be done on each and every one, so it took some time. Since about 2000, virtually everything that makes sense as an LKM has at least had the option of being an LKM.

How Do Modules Get Into The Kernel?

You can see what modules are already loaded into the kernel by running lsmod, which gets its information by reading the file /proc/modules.

When the kernel needs a feature that is not resident in the kernel, the kernel module daemon kmod execs modprobe to load the module in. modprobe is passed a string in one of two forms:

A module name like softdog or ppp.

A more generic identifier like char-major-10-30.

If modprobe is handed a generic identifier, it first looks for that string in the file /etc/modprobe.conf If it finds an alias line like:

alias char-major-10-30 softdog

it knows that the generic identifier refers to the module softdog.ko.

Next, modprobe looks through the file /lib/modules/version/modules.dep, to see if other modules must be loaded before the requested module may be loaded. This file is created by depmod -a and contains module dependencies. For example, msdos.ko requires the fat.ko module to be already loaded into the kernel. The requested module has a dependency on another module if the other module defines symbols (variables or functions) that the requested module uses.

Lastly, modprobe uses insmod to first load any prerequisite modules into the kernel, and then the requested module. modprobe directs insmod to /lib/modules/version/, the standard directory for modules. insmod is intended to be fairly dumb about the location of modules, whereas modprobe is aware of the default location of modules, knows how to figure out the dependencies and load the modules in the right order. So for example, if you wanted to load the msdos module, you’d have to either run:

insmod /lib/modules/2.6.11/kernel/fs/fat/fat.ko
insmod /lib/modules/2.6.11/kernel/fs/msdos/msdos.ko

or:

modprobe msdos

What we’ve seen here is: insmod requires you to pass it the full pathname and to insert the modules in the right order, while modprobe just takes the name, without any extension, and figures out all it needs to know by parsing /lib/modules/version/modules.dep.

Linux distros provide modprobe, insmod and depmod as a package called module-init-tools. In previous versions that package was called modutils. Some distros also set up some wrappers that allow both packages to be installed in parallel and do the right thing in order to be able to deal with 2.4 and 2.6 kernels. Users should not need to care about the details, as long as they’re running recent versions of those tools.

What is modprobe?

The modprobe utility is used to add and remove kernel modules to/from linux kernel. Linux kernel modules have .ko as module name extension. ‘modprobe’ is intelligent enough to load the dependency of a kernel module(if any) first and then loads the actual module.

5 modprobe Examples
1. Basic example to load an LKM

In the first example we will see how to load a LKM (kept at any path in system) using modprobe. Use the following steps to achieve this :

sudo ln -s /path/to/your-kernel-module /lib/modules/`uname -r`
sudo depmod -a
sudo modprobe your-kernel-module

for example, what I did was :

$ sudo ln -s lkm.ko /lib/modules/2.6.32-21-generic/
$ sudo depmod -a
$ sudo modprobe lkm

NOTE: If your module outputs some debug messages then confirmation of the loaded module could be achieved by looking at the logs from dmesg utility. Alternatively, the lsmod utility can be used to view the currently loaded modules
2. Unload a loaded using modprobe

The modprobe can also be used to remove the loaded module. Or in other words we can unload a loaded module through modprobe using the -r option.

$ sudo modprobe -r lkm

The above command unloads a currently loaded module ‘lkm’ from kernel.
3. Have a dry run

Sometimes we face problems like module not being loaded properly etc. In that case it becomes very important to debug and know the level at which the problem exists. It becomes crucial to know whether the problem is before loading or after loading. To facilitate this type of debugging, there exists option -n which if used, forces modprobe to do everything else except the final stage of loading the module.

$ sudo modprobe -vn lkm
insmod /lib/modules/2.6.32-21-generic/kernel/arch/x86/kernel/lkm.ko

I used the -v option along with -n so that some debugging info could be spitted out by modprobe.
4. Suppress the error information

Usually in some error condition, the modprobe utility would try to output some error info. If that kind of info is not needed, then the -q option is used to suppress this kind of info.

$ sudo modprobe lk
FATAL: Module lk not found.
$ sudo modprobe -q lk
$

So we see that in the above output, when the command was run without the -q option then an error was thrown while when -q was used the error got suppressed.
5. List the modules

If there is a requirement to list all the modules or modules with specific name then modprobe provides -l option to accomplish this

$ modprobe -l crc*
kernel/arch/x86/crypto/crc32c-intel.ko
kernel/crypto/crc32c.ko
kernel/lib/crc-ccitt.ko
kernel/lib/crc-itu-t.ko
kernel/lib/crc7.ko
$ modprobe -l rds
kernel/net/rds/rds.ko

Syntax and Options

modprobe [ -v ] [ -V ] [ -C config-file ] [ -n ] [ -i ] [ -q ] [ -b ] [ -o modulename ] [ modulename ] [ module parameters… ]

modprobe [ -r ] [ -v ] [ -n ] [ -i ] [ modulename… ]

modprobe [ -l ] [ -t dirname ] [ wildcard ]

modprobe [ -c ]

modprobe [ –dump-modversions ] [ filename… ]

Short Option Long Option Option Description
-v –verbose Print messages about what the program is doing. Usually modprobe only prints messages if something goes wrong.This option is passed through install or remove commands to other modprobe commands in the MODPROBE_OPTIONS environment variable.
-C –config This option overrides the default configuration directory/file (/etc/modprobe.d or /etc/modprobe.conf). This option is passed through install or remove commands to other modprobe commands in the MODPROBE_OPTIONS environment variable.
-c –showconfig Dump out the effective configuration from the config directory and exit.
-n –dry-run This option does everything but actually insert or delete the modules (or run the install or remove commands). Combined with -v, it is use-ful for debugging problems.
-i –ignore-install –ignore-remove This option causes modprobe to ignore install and remove commands in the configuration file (if any) for the module specified on the command line (any dependent modules are still subject to commands set for them in the configuration file).
-q –quiet Normally modprobe will report an error if you try to remove or insert a module it can’t find (and isn’t an alias or install/remove command). With this flag, modprobe will simply ignore any bogus names (the kernel uses this to opportunistically probe for modules which might exist).
-r –remove This option causes modprobe to remove rather than insert a module. If the modules it depends on are also unused, modprobe will try to remove them too. Unlike insertion, more than one module can be specified on the command line (it does not make sense to specify module parameters when removing modules).There is usually no reason to remove modules, but some buggy modules require it. Your kernel may not support removal of modules.
-f –force Try to strip any versioning information from the module which might otherwise stop it from loading: this is the same as using both –force-vermagic and –force-modversion. Naturally, these checks are there for your protection, so using this option is dangerous.
This applies to any modules inserted: both the module (or alias) on the command line and any modules it on which it depends.

What is insmod?

insmod command is used to insert modules to Linux kernel.

3 insmod Examples
1. Specify module name as an argument

The following command insert the module airo to the Linux kernel.

# insmod kernel/drivers/net/wireless/airo.ko

Once you’ve inserted the module, use lsmod command to verify that the module has been inserted successfully as shown below.

# lsmod | grep airo
Module Size Used by
airo 66291 0

Note: It is recommended that you use modprobe command for all your Kernel module manipulation, including inserting a module.

All the modules that are available to be inserted to the kernel are listed in the modules.dep file as shown below.

# more /lib/modules/`uname -r`/modules.dep

(or)

# more /lib/modules/2.6.32-100.28.5.el6.x86_64/modules.dep

2. Insert a module with any arguments

If there are any arguments that needs to be passed for the module, give that as 3rd option as shown below.

The following command insert the module dummy to the Linux kernel. In this example, the dummy module takes two arguments type and debug. You can set the values for type and debug arguments and pass it to dummy module as shown below.

# insmod dummy type=”wpa” debug=1

3. Specify module name interactively

Let us assume that you want to insert a pcmcia module called ‘axnet_cs’.

First, verify to make sure this module is listed in the modules.dep file

# grep axnet_cs /lib/modules/`uname -r`/modules.dep
kernel/drivers/net/pcmcia/axnet_cs.ko:

Following is the full path of this file.

# ls /lib/modules/`uname -r`/kernel/drivers/net/pcmcia/axnet_cs.ko
/lib/modules/2.6.32-100.28.5.el6.x86_64/kernel/drivers/net/pcmcia/axnet_cs.ko

Use insmod – and enter the module name interactively.

# insmod –
kernel/drivers/net/pcmcia/axnet_cs.ko

Or, you can use < to give the module name as shown below.

# insmod – < kernel/drivers/net/pcmcia/axnet_cs.ko

Verify to make sure the module got inserted successfully.

# lsmod | grep axnet
axnet_cs 14627 0

Syntax and Options

Syntax:

insmod [ filename ] [ module options… ]

Leave a Reply

Your email address will not be published. Required fields are marked *