Different Types Of Kernel Modules?
There are many kernel modules that are shipped with the kernel source code and also components that can be added to the kernel as a module. There are also the so-called "out-of-tree" modules that have not yet been added to the kernel official source code but are, more or less, compatible with the kernel and theoretically can be added to the kernel source either dynamically at the run-time or build into the kernel source code at the compile time. You can run one of these commands to get an idea of how many different modules there are in the particular kernel version available on your system:
find /lib/modules/`uname -r`/kernel -type f \( -name "*.xz" -o -name "*.ko" \) | wc -l
grep =m /usr/src/kernels/`uname -r`/.config | wc -l
grep =m /boot/config-`uname -r` | wc -l
Depending on what version of the Linux kernel you have and how you have built or installed it, you might get very different numbers from each of the above commands. Nevertheless, the numbers that you will see are large and usually more than a few thousand. That means that there are many kernel modules in a normal kernel source tree/installation.
However, not all of these modules are used in a normal system. There are usually a handful of modules that are utilized by a running kernel, the rest are practically never added to the kernel and naturally never used.
To utilize a particular kernel module we must add the module source code to the kernel. There are two ways to do this; we can do this at the compile-time while we are building the kernel from the source, or we can dynamically load a module into the kernel source code at the run-time (One of the most interesting features of the Linux kernel), so in a way modules that are actually utilized have either been compiled or loaded into the kernel and for the purposes of this guide this distinction is important.
Which Modules Have Been Compiled Into The Kernel?
There are different ways to obtain this information. Here is one way to find the list of built-in modules:
awk -F"/" '{print $NF}' /lib/modules/`uname -r`/modules.builtin | cut -d "." -f1
Which Modules Have Been Dynamically Loaded Into The Kernel?
Similarly, there are different ways to obtain that information as well. Here are handy commands that outputs the list of loaded kernel modules:
find /sys/module/ -type f -name "initstate" -print | awk -F"/" '{print $(NF-1)}'
cut -d " " -f1 /proc/modules
lsmod | cut -d " " -f1
How To See The Current Parameters Passed To A Module?
Linux Kernel's highly modular design guarantees that each module has its own set of options and parameters that can be passed to the module at different stages of that module integration into the kernel and these parameters modify its behavior of that module . Most modules' default set of options do usually suffice for most systems, but occasionally we might need to pass a different set of parameters to a module to achieve a certain task.
The following command should list every currently loaded/compiled module along with the list of parameters that have already been passed to that module: (You need to install the "tree" command before being able to run this command)
find /sys/module/ -type d -name "parameters" -print | xargs tree -a -CA
You can also run the following to see the current list of parameters passed to only the built-in modules: (This file might not exist on older kernels and even if it does the data returned it's not very readable, so the above command is usually preferred)
cat /lib/modules/`uname -r`/modules.builtin.modinfo
Alternatively, you can always use the modinfo binary to see any module's list of parameters: (MOD_NAME needs to be replaced with the name of the module)
/usr/sbin/modinfo -p MOD_NAME
How To Pass New Parameters To A Module?
Occasionally you need to pass different parameters to a module or modify the value of an existing parameter, there are three different ways to perform such a task:
1- Using the Kernel Command-Line Interface: (For Compiled Modules Only)
The kernel command-line interface gives up the opportunity to pass configuration options to the kernel at the boot time, right when the kernel is starting.
There are three ways to pass options to the kernel, the modules included, and thus control its behavior:
- When building the kernel—in the kernel's
config
file. (Build-Time Configuration) - When starting/booting the kernel—using command line parameters or the bootloader configuration files. (Boot-Time Configuration)
- At runtime—through the files in
/proc/sys/
(see man sysctl) and/sys/
. (Run-Time Configuration)
Here we are only interested in the second method, the boot-time configuration. Through this method, we are able to pass parameters not only to the kernel but also to the built-in modules that have been previously compiled into the kernel (This works for only the compiled modules since the system hasn't still booted so the loaded modules are not yet in the memory).
The syntax for passing parameters consists of the module name (MOD_NAME) followed by a dot (.) and then the name of the parameter to be modified (PARAM_NAME):
MOD_NAME.PARAM_NAME
You can check the parameters your system was booted up with by running cat /proc/cmdline
For further information on how to use the kernel command-line interface you can refer to these links:
https://wiki.archlinux.org/index.php/kernel_parameters
https://www.thegeekdiary.com/centos-rhel-7-how-to-add-a-kernel-parameter-only-to-a-specific-kernel/
https://www.thegeekdiary.com/centos-rhel-7-how-to-modify-the-kernel-command-line/
2- Using The modprobe Utility: (For Loaded Modules Only)
You can also use the kmod package and the modprobe utility to modify a parameter when loading a module dynamically. The syntax is as follows:
/usr/sbin/modprobe MOD_NAME PARAM_NAME
3- Using The sysfs File System: (For All Modules)
And finally, you can use the all-powerful sysfs interface to pass new parameters to any module on your system. All you need to do is to find the right file associated with each parameter and then echo a new value into that file:
echo “VALUE” >> /sys/module/MOD_NAME/parameters/PARAM_NAME
This basically means that even modules that have been compiled into the kernel can also be changed at run-time, which just goes to show how infinitely flexible and unbelievably configurable the Linux kernel really is.