Loading a kernel module into the kernel during runtime involves several steps that allow the module to become part of the operating system’s kernel and extend its functionality. The process typically includes the following stages:
-
Compilation of the Module:
- Before loading a kernel module, it needs to be compiled into a binary format compatible with the target kernel. The compilation generates a kernel module file (with a
.koextension) containing the compiled code and related information.
- Before loading a kernel module, it needs to be compiled into a binary format compatible with the target kernel. The compilation generates a kernel module file (with a
-
Module Loading Command:
- The primary command used to load a kernel module is
insmod(insert module) on Linux-based systems. The basic syntax is as follows:
Theinsmodinsmodcommand is used to insert the specified module into the running kernel.
- The primary command used to load a kernel module is
-
Dependency Resolution:
- When a module is loaded, the kernel checks for any dependencies that the module might have. If dependencies are not met, the kernel attempts to load them first. Modern package management tools and kernel module management systems often handle dependency resolution automatically.
-
Symbol Resolution:
- The kernel resolves symbols used by the module, mapping symbolic names to their corresponding memory addresses. This ensures that the module can correctly reference functions and data defined within the kernel or other modules.
-
Initialization Routine Execution:
- The kernel calls the initialization routine specified by the module during compilation. This routine is typically named
module_init()and is marked with the__initmacro. The initialization routine contains code that sets up the module, allocates resources, and performs any necessary initialization tasks.
- The kernel calls the initialization routine specified by the module during compilation. This routine is typically named
-
Initialization Success Check:
- The initialization routine returns a status code, typically 0 for success and a non-zero value for failure. The kernel checks this return value to determine whether the module was loaded successfully.
-
/proc/modules Update:
- The
/proc/modulesfile, which lists the currently loaded modules, is updated to reflect the newly loaded module. The entry for the module includes information such as its name, size, and memory usage.
- The
-
Dynamic Symbol Resolution:
- The kernel resolves any remaining symbol references dynamically at runtime. This includes symbols that may be provided by other modules or parts of the kernel.
-
Syslog and dmesg:
- Information about the loading of the kernel module, including any diagnostic messages or errors, is logged in system logs. The
dmesgcommand or tools likejournalctlon Linux can be used to view these log entries.
- Information about the loading of the kernel module, including any diagnostic messages or errors, is logged in system logs. The
-
Module Verification:
- Some systems may include mechanisms to verify the integrity of kernel modules before loading. This is particularly important for security purposes. For example, Secure Boot on UEFI systems may enforce signature checks on kernel modules.
Once a kernel module is successfully loaded, it becomes an integral part of the running kernel, contributing its functionality to the operating system. It can be used to support new hardware, add file systems, enhance networking capabilities, or perform other tasks based on its intended purpose.
It’s important to note that the process of loading kernel modules may vary slightly depending on the specific operating system and kernel version in use. Additionally, certain systems may have security policies or configurations that affect the loading of kernel modules.