Linux kernel modules
Table of contents
2. Getting information about modules
3. Automatic module loading using systemd
4. Manual processing of modules (enable and disable modules and drivers)
4.1 How to use the driver without installing it
5.1 How to block all network interfaces on a computer
5.2 How to reliably turn off the webcam
5.3 How to turn off Bluetooth to disable pairing and any connections
8. Kernel modules troubleshooting
8.3 modprobe: FATAL: Module … not found in directory /lib/modules/…
What are kernel modules
Kernel modules are pieces of code that can be loaded and unloaded into the kernel on demand. They extend the functionality of the kernel without having to reboot the system. The module can be configured as built-in to the kernel or loaded while the operating system is running.
Examples of kernel modules are drivers for various devices.
In this article you will learn:
- how to find out which kernel modules are running (loaded)
- how to find out which driver is used for the specified device and how to get information about this driver
- how to reliably disable devices (for example, network cards, webcams and others) so that they cannot be turned on and used
- how to try a new driver without installing it in the system
Getting information about modules
Modules are stored in the /usr/lib/modules/KERNEL_RELEASE directory. The current folder with modules can be found with the command:
echo /lib/modules/`uname -r`
Output Example:
/lib/modules/5.6.14-arch1-1
Module names often contain underscores (_) or hyphens (-); these symbols are interchangeable in the modprobe commands and in the configuration files in the /etc/modprobe.d/ directory.
The lsmod command shows the drivers and other modules that are currently loaded. To see which modules are currently loaded, type:
lsmod
or command
kmod list
In fact, this is one and the same. Information is read from /proc/modules and these commands only display it in a more understandable way.
To display information about the module, use the modinfo command:
modinfo MODULE_NAME
If you get an error:
bash: modinfo: command not found
Then run modinfo with sudo.
For example, to find out information about the iwlwifi module:
modinfo iwlwifi
How to understand modinfo output
modinfo output is extensive and contains a lot of information.
The “filename” line shows the full path to the module file.
The line “author” contains information about the creator of the module, for example, “Copyright (c) 2003-2015 Intel Corporation <linuxwifi@intel.com>”
In the “description” line is a description of the module, for example, “Intel (R) Wireless WiFi driver for Linux”.
Let’s consider how to interpret strings
- firmware
- alias
- intree
- vermagic
on the example of the i915 module
modinfo i915
Output snippet:
filename: /lib/modules/4.2.0-1-amd64/kernel/drivers/gpu/drm/i915/i915.ko license: GPL and additional rights description: Intel Graphics author: Intel Corporation [...] firmware: i915/skl_dmc_ver1.bin alias: pci:v00008086d00005A84sv*sd*bc03sc*i* [...] depends: drm_kms_helper,drm,video,button,i2c-algo-bit intree: Y vermagic: 4.2.0-1-amd64 SMP mod_unload modversions parm: modeset:Use kernel modesetting [KMS] (0=DRM_I915_KMS from .config, 1=on, -1=force vga console preference [default]) (int) [...]
firmware:
firmware: i915/skl_dmc_ver1.bin
Many devices require two things to work properly: a driver and firmware. The driver requests firmware from the file system in /lib/firmware. This is a special file necessary for hardware, it is not a binary file. Then the diver uploads the firmware to the device. The firmware performs programming of the equipment inside the device.
alias:
alias: pci:v00008086d00005A84sv*sd*bc03sc*i*
This entry can be divided into parts by colons (:)
- pci: device type, pci or usb
- v00008086: v denotes the identifier of the supplier, it identifies the vendor of the equipment. This list is maintained by the PCI Special Interest Group. The number 0x8086 means “Intel Corporation”.
- d00005A84: d is the device identifier selected by the vendor. This identifier is usually connected to the vendor identifier to create a unique 32-bit identifier for the hardware device. There is no official list.
- sv*, sd*: subsystem provider version and subsystem device version for further device identification (* indicates that it will correspond to anything)
- bc03: base class. It determines what kind of device it is; IDE interface, Ethernet controller, USB controller, … bc03 means display controller. You can notice them from the output of lspci because lspci maps the number and class of the device.
- sc*: subclass of the base class.
- i*: interface
intree:
intree: Y
All kernel modules begin their development as outside the tree. Once a module is accepted for inclusion, it becomes a module inside the tree. Modules without this flag (set to N) can ruin the kernel.
vermagic:
vermagic: 4.2.0-1-amd64 SMP mod_unload modversions
When the module loads, the vermagic string is checked for compliance with the current kernel version. If they do not match, you will receive an error and the kernel will refuse to load the module. You can overcome this by using the --force flag in modprobe. Naturally, these checks exist for your protection, so using this option is dangerous.
To display a list of options installed for a loaded module:
systool -v -m MODULE_NAME
If you get an error:
bash: systool: command not found
Then install the sysfsutils package.
Example output for the iwlwifi module:
systool -v -m iwlwifi
To display the full configuration of all modules:
modprobe -c | less
To display the configuration of a specific module:
modprobe -c | grep MODULE_NAME
To list the dependencies of a module (or an alias), including the module itself:
modprobe --show-depends MODULE_NAME
Automatic module loading using systemd
Today, loading all the necessary modules is performed by udev automatically, so there is no need to put the modules in any configuration file. However, in some cases, you may need to download an additional module during the boot process of the computer or add another module to the blacklist for the computer to work properly.
Kernel modules can be explicitly listed in the files in /etc/modules-load.d/ for systemd to load them when the computer is turned on. Each configuration file has a name in the style of /etc/modules-load.d/ <program>.conf. Configuration files simply contain a list of kernel module names for loading, separated by newline characters. Empty lines and lines whose first non-whitespace character is # (hash) or ; (semicolon) are ignored.
Sample file /etc/modules-load.d/virtio-net.conf
# Load virtio_net.ko when you turn on the computer virtio_net
In addition to the specified directory, configuration files from /run/modules-load.d/*.conf and /usr/lib/modules-load.d/*.conf are also read.
Note that it is usually best to rely on automatic loading of modules using PCI identifiers, USB identifiers, DMI identifiers, or similar triggers encoded in the kernel modules themselves, instead of a static configuration like this. In fact, most modern kernel modules are already prepared for automatic loading.
Manual processing of modules (enable and disable modules and drivers)
Kernel modules are handled by the tools provided by the kmod package. You can use these tools manually.
Note. If you have updated the kernel but have not yet restarted the computer, modprobe will fail with no error message and exit with code 1, since the /usr/lib/modules/$(uname -r)/ path no longer exists.
To load a module, use a command of the form:
sudo modprobe MODULE_NAME
To load a module by file name (that is, one that is not installed in /usr/lib/modules/$(uname -r)/):
sudo insmod FILE_NAME [ARGUMENTS]
To unload (turn off) the module:
sudo modprobe -r MODULE_NAME
Or an alternative command:
sudo rmmod MODULE_NAME
How to use the driver without installing it
Let's look at a real-life example when starting a driver from a file can come in handy.
Let’s consider the driver repository for the RTL8812AU/21AU and RTL8814AU chipsets as an example.
These drivers are designed to operate such modern Wi-Fi dongles with support for Wi-Fi AC standard as:
- Alfa AWUS1900 (chipset: Realtek RTL8814AU)
- TRENDnet TEW-809UB (chipset: Realtek RTL8814AU)
- ASUS USB-AC68 (chipset: Realtek RTL8814AU)
- Alfa AWUS036ACH (chipset: Realtek RTL8812AU)
- Alfa AWUS036AC (chipset: Realtek RTL8812AU)
- ASUS USB-AC56 (chipset: Realtek RTL8812AU)
These drivers support monitor mode and wireless injection, that is, they are suitable for wireless security audit of Wi-Fi networks on 2.4 and 5 GHz, including those with support for Wi-Fi standard AC.
In principle, Kali Linux repositories already have this driver:
apt show realtek-rtl88xxau-dkms
But its version is 5.6.4. But version 5.7.0 is already available. Suppose we want to try version 5.7.0 without installing it on a system.
So, delete the version from the repository (if it was installed)
sudo apt remove realtek-rtl88xxau-dkms
Check that the module is not loaded:
sudo lsmod | grep 88XXau
And when I try to download it, an error occurs:
sudo modprobe 88XXau
module not found:
modprobe: FATAL: Module 88XXau not found in directory /lib/modules/5.6.0-kali1-amd64
Or such an error:
modprobe: ERROR: could not insert '88XXau': Unknown symbol in module, or unknown parameter (see dmesg)
That is, unknown symbol in module. The essence is the same – the module was not found, but previously existed, so references to the dependency lists remained from it.
Install the dependencies necessary to compile this driver:
sudo apt install build-essential bc libelf-dev
We clone the repository – pay attention to the use of the -b option with which the branch of interest is indicated (in this case, the name of the branch matches the version of the driver):
git clone https://github.com/aircrack-ng/rtl8812au -b v5.7.0
We compile, but do not do the installation, since we do not want to install this module:
cd rtl8812au make
We have two ways to load (enable) a module – using insmod or using the modprobe command. The insmod command is more convenient, because you can specify a compiled driver file, and the modprobe command handles dependencies better, so let's consider both options.
Load a module without installing (using insmod)
To include a module from a file, use a command of the form:
sudo insmod FILE_NAME [ARGUMENTS]
The module files have the .ko extension, in our case the file name is 88XXau.ko, so the command is as follows:
sudo insmod ./88XXau.ko
Check if the module has been loaded:
sudo lsmod | grep 88XXau
Output:
88XXau 3067904 0 cfg80211 864256 1 88XXau usbcore 315392 6 ohci_hcd,ehci_pci,usbhid,ehci_hcd,ohci_pci,88XXau
The first line shows that the 88XXau module is loaded, and the next lines show the modules that 88XXau uses (that is, which are dependencies for it).
Load a module without installing (using modprobe)
The second option is a bit more complicated to configure, but you do not need to specify the full path to the driver file to load the module.
Unload the module if it was loaded earlier:
sudo rmmod 88XXau
Now we will make the system think that the module is installed, although in reality it is not. To do this, we will create a symbolic link from the .ko file to the /lib/modules/`uname -r` folder:
sudo ln -s /PATH/TO/MODULE.ko /lib/modules/`uname -r`
In our case, to do this, run the following command:
sudo ln -s `pwd`/88XXau.ko /lib/modules/`uname -r`
Update the list of dependencies of all modules (by the way, the -a switch in the following command can be skipped, because it is assumed by default):
sudo depmod -a
Now you can use the regular modprobe command to load the module:
sudo modprobe 88XXau
Check the module version:
sudo modinfo 88XXau
Pay attention to the lines:
filename: /lib/modules/5.6.0-kali1-amd64/88XXau.ko version: v5.7.0_34085.20200313
Version v5.7.0 is used – this is exactly what we achieved.
The described methods for starting modules are suitable for a one-time or occasional driver launch. For permanent use, it is recommended to perform a normal installation a module, in which case it will support DKMS.
DKMS
Drivers can be installed using DKMS. This is a system that automatically recompiles and installs kernel modules when installing or updating a new kernel. To use DKMS, install the dkms package.
Using DKMS, drivers from official repositories are installed. Also, using DKMS, you can install drivers from other repositories (for example, rtl8812au, which was taken as an example just above, it supports) – to do this, follow the official installation instructions from the developers, and the method for starting the driver described above is designed to testing.
Modules blacklisting
Blacklisting, in the context of kernel modules, is a mechanism that prevents the loading of a kernel module. This can be useful if, for example, related equipment is not required or if loading this module causes problems: for example, there may be two kernel modules that are trying to control the same hardware component, and loading them together will lead to a conflict.
Using Files in /etc/modprobe.d/
Create a .conf file inside /etc/modprobe.d/ and add a line for each module that you want to add to the blacklist using the blacklist keyword. For example, if you want to prevent the pcspkr module from loading, create the file /etc/modprobe.d/nobeep.conf and add the line to it:
blacklist pcspkr
Some modules are loaded as part of initramfs. That is, modules can be modules can be classified as:
- loaded from .ko files
- loaded as part of initramfs
To prohibit the loading of modules of the first type (loaded from .ko files), it is enough to record this module in the /etc/modprobe.d/*.conf file with the blacklist directive.
For modules of the second type (loaded as part of initramfs), in addition to creating the configuration file, it is also necessary to recreate the kernel.
Note. The blacklist command will blacklist the module so that it does not load automatically. But at the same time, the module can be loaded if another module, not included in the black list, depends on it, and you can still load the module manually. However, there is a workaround for this behavior; the install command tells modprobe to run a user command instead of inserting the module into the kernel as usual, so you can force the module to never load using the construction discussed below. Suppose you created the file /etc/modprobe.d/blacklist.conf to block the loading of the module MODULE_NAME. To do this reliably, add to this file:
blacklist MODULE_NAME install MODULE_NAME /bin/true
This will reliably block the loading of the specified module, as well as any other, depending on it.
How to recreate the kernel to block modules
If you block modules that are loaded from initramfs, then after adding them to the /etc/modprobe.d/*.conf file, you need to recreate the kernel.
On Debian, Kali Linux, Linux Mint, Ubuntu and their derivatives this is done like this:
sudo update-initramfs -u sudo reboot
In Arch Linux, BlackArch, and their derivatives, this is done like this:
sudo mkinitcpio -g /boot/initramfs-linux.img -k /boot/vmlinuz-linux
Arch Linux command
mkinitcpio -M
prints all automatically detected modules: to prevent some of these initramfs from loading, blacklist them in the .conf file in /etc/modprobe.d and it will be added by the modconf hook during image generation. Launch
mkinitcpio -v
to list all the modules involved by various hooks (for example, filesystems hook, block hook, etc.).
Blacklisting modules at the start of Linux boot (disabling modules on the kernel command line)
This can be very useful if a faulty module makes it impossible to boot your system. You can blacklist modules in the bootloader menu. Just add
module_blacklist=MODULE-NAME1,MODULE-NAME2,MODULE-NAME3
in a line with kernel boot parameters.
Examples of editing kernel boot parameters for popular distributions can be found in the article “How to reset a forgotten login password in Linux”. Also see the article “How to change Linux boot parameters in UEFI”.
Note. If you blacklist more than one module, keep in mind that they are separated only by commas. Spaces or anything else can break the syntax.
Consider practical examples where a user may need to block the loading of kernel modules.
How to block all network interfaces on a computer
Suppose it is necessary that any network activity, that is, both wired and wireless networks, is blocked on the computer. There is an rfkill command, but it is designed to block only wireless networks. Therefore, we find another way.
The algorithm of actions is as follows:
- We will determine which drivers are used by network devices.
- Blacklist these drivers
To find out which drivers are used in Linux for network cards, run the command:
sudo lshw -C network
The “configuration:” lines contain information about the drivers. For a wireless card it is “driver=iwlwifi”, and for a wired network interface it is “driver=r8169”.
Create the file /etc/modprobe.d/block-network.conf and add to it:
blacklist iwlwifi install iwlwifi /bin/true blacklist r8169 install r8169 /bin/true
This is how the network setup looks in normal condition, the wired and wireless adapters are visible:
After reboot, it will not be possible to turn on the network, because the computer will not be able to use network interfaces without drivers:
When trying to load modules manually, for example:
sudo modprobe iwlwifi
These modules will not load thanks to the install command.
You cannot turn on any network until you delete the /etc/modprobe.d/block-network.conf file and reboot. However, if other network adapters are plugged, they will be used. This method will reliably protect against accidental use of the network, provided that you control the plugging of new physical devices to the computer.
How to reliably turn off the webcam
On some new laptop models, you can close the webcam with a shutter – in case you are afraid that a hacker might hack your computer and use the webcam of your laptop to look at you.
Now we will learn how to disable the webcam driver so that it cannot be used.
Even if you have a laptop, most likely the web camera is connected inside the case to a USB hub, that is, it is a USB device. To list USB devices in the system, use the command:
lsusb
Pay attention to IMC Networks USB2.0 HD UVC WebCam in the list above – this is the laptop’s webcam.
To determine the drivers that are needed for any USB or PCI device to work on your system, use the following commands:
# To list only USB devices and their drivers usb-devices # To list only PCI devices and their drivers lspci -k # To list both USB and PCI devices and their drivers sudo lshw
We use the command:
usb-devices
We see that the uvcvideo driver is used for the USB2.0 HD UVC WebCam device.
We create the file /etc/modprobe.d/block-webcam.conf and block the launch of the uvcvideo kernel module in it:
blacklist uvcvideo install uvcvideo /bin/true
After rebooting, the system will not be able to use the webcam until the block-webcam.conf file is deleted and the system is rebooted.
How to turn off Bluetooth to disable pairing and any connections
As you can see, the blueman applet, and therefore Bluetooth, is working.
To disable bluetooth module create /etc/modprobe.d/blacklist.conf file:
sudo gedit /etc/modprobe.d/blacklist.conf
and copy the following into it:
blacklist bluetooth install bluetooth /bin/true
Restart your computer for the changes to take effect.
As you can see, Bluetooth is no longer working:
Setting module options
To pass an option to the kernel module, you can pass them manually using modprobe or make sure that certain parameters are always applied using the modprobe configuration file or using the kernel command line.
Manually at boot time using modprobe
The main way to pass parameters to a module is to use the modprobe command. Parameters are specified on the command line using simple key=value assignments:
modprobe MODULE-NAME PARAMETER-NAME=PARAMETER-VALUE
Using files in /etc/modprobe.d/
Files in the /etc/modprobe.d/ directory can be used to transfer module settings to udev, which will use modprobe to control module loading during system boot. The configuration files in this directory can have any name if they end with the .conf extension, for example /etc/modprobe.d/myfilename.conf. Syntax:
options MODULE-NAME PARAMETER-NAME=VALUE-PARAMETER
For example, the contents of the file /etc/modprobe.d/thinkfan.conf:
# on ThinkPads, this setting allows the thinkfan daemon to control fan speed options thinkpad_acpi fan_control=1
Adding module options during system boot (using the kernel command line)
If the module is built into the kernel, you can also pass options to the module using the kernel command line. For all common bootloaders, the correct syntax is:
MODULE-NAME.PARAMETER-NAME=PARAMETER-VALUE
For instance:
thinkpad_acpi.fan_control=1
Aliases
Aliases are alternative names for the module. For instance:
alias MY-MOD VERY-LONG-MODULE-NAME
means you can use
modprobe MY-MOD
instead
modprobe VERY-LONG-MODULE-NAME
You can also use shell-style wildcards, so
alias my-mod* really_long_modulename
means that
modprobe my-mod-something
has the same effect.
To create an alias in the configuration file /etc/modprobe.d/myalias.conf:
alias MY-MOD VERY-LONG-MODULE-NAME
Some modules have aliases that are used to automatically load them when the application needs them. Disabling these aliases can prevent automatic loading, but it still allows you to load modules manually.
Sample file /etc/modprobe.d/modprobe.conf
# Prevent Bluetooth auto download alias net-pf-31 off
Kernel modules troubleshooting
Modules do not load
If a certain module does not load, and in the boot log
journalctl -b
it says that the module is in the blacklist, but there is no corresponding entry in the /etc/modprobe.d/ directory, check another modprobe folder for the presence of the blacklist entry: /usr/lib/modprobe.d/.
A module will not be loaded if the "vermagic" string contained within the kernel module does not match the value of the currently running kernel. If it is known that the module is compatible with the current running kernel the "vermagic" check can be ignored with modprobe --force-vermagic.
Warning. Ignoring version checks for a kernel module can lead to a kernel crash or unpredictable system behavior due to incompatibility. Use --force-vermagic with extreme caution.
modprobe: ERROR: could not insert '…': Unknown symbol in module, or unknown parameter (see dmesg)
Example:
modprobe: ERROR: could not insert '88XXau': Unknown symbol in module, or unknown parameter (see dmesg)
The error is caused by the fact that the module was previously present in the system and an entry in the list of dependencies was left about it, but at the time of the error the module was missing (removed).
To update the list of dependencies, run the command:
sudo depmod -a
Another possible reason for the error is that the dependency required for the module has not been loaded. For example, for Wi-Fi adapters, the required dependency is cfg80211, to load this module, run the command:
sudo modprobe cfg80211
modprobe: FATAL: Module … not found in directory /lib/modules/…
Example:
modprobe: FATAL: Module 88XXau not found in directory /lib/modules/5.6.0-kali1-amd64
Means that the module you are trying to run does not exist.
Possible reasons:
- typo in the module name
- the package containing the specified module is not installed or removed
If previously the module (driver) was launched, but then the indicated error appeared, then it may be due to the fact that the kernel was updated, and the module for the new version of the kernel was not compiled.
Related articles:
- How to brute-force passwords using GPU and CPU in Linux (100%)
- Wi-Fi adapter Qualcomm Atheros QCA9377 does not capture data packets in monitor mode (SOLVED) (86%)
- How to install the Realtek RTL8821CE driver (86%)
- How in Windows view the contents of a Linux disk and copy files from it (58.5%)
- How to use Android phone as GPS sensor in Linux (58.5%)
- Utilities for information gathering, OSINT and network analysis in Windows and Linux (RANDOM - 8.5%)
Very interresting article as usual
thx