About debugging Linux kernel modules
Linux kernel modules provide a way to extend the functionality of the kernel, and are typically used for things such as device and file system drivers. Modules can either be built into the kernel or can be compiled as a loadable module and then dynamically inserted and removed from a running kernel during development without having to frequently recompile the kernel. However, some modules must be built into the kernel and are not suitable for loading dynamically. An example of a built-in module is one that is required during kernel boot and must be available prior to the root file system being mounted.
You can set source-level breakpoints in a module after loading the module debug information into the debugger. For example, you can load the debug information using add-symbol-file modex.ko. To set a source-level breakpoint in a module before it is loaded into the kernel, use
break -p to create a pending breakpoint. When the kernel loads the module, the debugger loads the symbols and applies the pending breakpoint.
When debugging a module, you must ensure that the module on your target is the same as that on your host. The code layout must be identical, but the module on your target does not require debug information.
To debug a module that has been built into the kernel, the procedure is the same as for debugging the kernel itself:
- Compile the kernel together with the module.
- Load the kernel image on to the target.
- Load the related kernel image with debug information into the debugger
- Debug the module as you would for any other kernel code.
Built-in (statically linked) modules are indistinguishable from the rest of the kernel code, so are not listed by the
info os-modules command and do not appear in the Modules view.
The procedure for debugging a loadable kernel module is more complex. From a Linux terminal shell, you can use the
rmmod commands to insert and remove a module. Debug information for both the kernel and the loadable module must be loaded into the debugger. When you insert and remove a module the debugger automatically resolves memory locations for debug information and existing breakpoints. To do this, the debugger intercepts calls within the kernel to insert and remove modules. This introduces a small delay for each action whilst the debugger stops the kernel to interrogate various data structures.
NoteA connection must be established and Operating System (OS) support enabled within the debugger before a loadable module can be detected. OS support is automatically enabled when a Linux kernel image is loaded into the debugger. However, you can manually control this by using the