Linux Kernel Modules Internals | Module.order, Module.symvers
In normal c programming we will use compilation model where the c program goes through the serveral compilation stages before a final executable is generated.
hello.c → preprocessing → compilation → hello.o → linking → executable
compilation flow of a normal c program.
Similarly in linux kenrel programming also we will have a build process, but here instead of creating a executable we will create a lodable kernel module with .ko extenstion.
hello.c → hello.o → hello.mod.c → hello.mod.o → hello.ko
kernel build process, this is loadable kenrel module that can be inserted into the kenrel using the commands like
sudo insmod hello.ko
to remove the kernel module use the below command
sudo rmmod hello
now kenrel module is removed, this is how a kernel build system is used to build the module load the module and unload the module.
Now let us see how a kernel build system works
Kernel Build System (Kbuild)
Kernel modules are build using the Kbuild system of kernel, Kbuild is hte build infrastructure used by the linux kenrel to compile the kenrel source code, build kernel modules, manage dependencies, generate metadata files.
so here instead of compiling directly with gcc kenrel modules are compiled thorugh kernel makefiles and Kbuild rules.
for example
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
explanation:
-C -> change directory to kenrel build directory
M=$(pwd) → directory containing the module source
modules → tells kernel build system to build modules
Kernel Module Makefile:
Every Kernel module requires a make file, example make file looks like
obj-m := hello.o
here
-
obj-mmeans object module -
hello.otells Kbuild that a module named hello must be built
from the above command Kbuild autmaticallky knows that it must generate hello.ko
How Kbuild detects source files:
Once Kbuild reads the Makefile it assumes that a source files is created and exists in same directory, if the file is in some other path you should mention the path and if the file does not exist in the mentioned directory then it will give and error and compilation will fail.
No rule to make target 'hello.o'
example error
Kernel module compilation flow:
hello.c
↓
hello.o
↓
hello.mod.c
↓
hello.mod.o
↓
Linking by modpost
↓
hello.ko
let us understand each step
STEP 1: Source file compilation
first the source file is compiled into an object file for example
hello.c → hello.o
this is similar to c compilation
STEP 2: Generation of .mod.c
during the module compilation Kbuild automaticallky generates a file called
hello.mod.c
this file contains meta data about the kernel module, this meta data include
modulename, moudle license, versioning information about the module, kenrel symbol dependencies, module initialization functions, module exit functions.
STEP 3: Compile .mod.c
now the generated ile is compiled into the .o file which is .mod.o so now there are two object files.
hello.o
hello.mod.o
let us see more about them in upcomming lectures
STEP 4: Linking Using modpost
now then next stage in kenrel building uses a kenrel tool called modpost, this performs seveal important tasks like checking module symbl dependencies, verifies exported symbols, generates the version information, links module objects, and after linking
hello.o + hello.mod.o → hello.ko
final hello.ko is generated, this is the loadable kernel module.
so below are the files generated, in build process let us understand them in detail.
hello.c
Makefile
hello.o
hello.mod.c
hello.mod.o
hello.ko
Module.symvers
Modules.order
some files are very important, let us understand them,
Modules.order:
what is Modules.order, it is a plain text file generated during kernel module build, it is lists all modules in order they were built.
why we need moudles.order?
Kernel Build Systems should know the order of the module compilation, because some modules depend on other modules, therefore build system must build the modules in the correct order, install the modules correctly, package modules properly.
Makefile uses Modules.order during:
make modules
make modules_install
this ensures modules are installed in the correct dependency order
Module.symvers
what is Module.symvers and why we need Module.symvers?
Module.symvers is a symbol version table generated during the kernel module build, it contains all exported kernel symbols, these symbols come from
EXPORT_SYMBOL
EXPORT_SYMBOL_GPL
this is used inside kenrel code, for example :
0x1db7034a printk vmlinux
format
symbol_name version_hash module_name
example
printk 0x1db7034a vmlinux
Why we need Module.symvers?
it is used for external module compilation, when building modules outside the kernel source tree, the module needs to know which symbol exist in the kenrel, what version of hte symbol exists, whether API compatibility exists so build system checks for Module.symvers.
Role in CONFIG_MODVERSIONS:
if the kenrel is compiled with
CONFIG_MODVERSIONS
then each exported symbol has version hash, this helps to ensure ABI compatibility, modules match the kernel version. If symbol versions mismatch module loading fails.
When module.symvers is empty:
sometimes you will observe
Module.symvers (empty)
this happens because, you are not using any of the external exported symbols, your module does not export symbols, therefore the table remains empty.
Difference between Modules.order and Modules.symvers
| File | Purpose |
| -------------- | ------------------------------- |
| Modules.order | Defines module build order |
| Module.symvers | Stores exported symbol versions |
conclusion, relationship between modules.order and modules.symvers
Modules.order
↓
Defines module build order
Module.symvers
↓
Defines symbol dependencies
so
Modules.order → module build sequence
Module.symvers → exported kernel symbols
hope you are clear with relation between Module.order module.symvers.
External module compilation flow:
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
below is the process, kernel build system performs.
1. Read Makefile
2. Detect obj-m := module.o
3. Locate module.c
4. Compile module.c → module.o
5. Generate module.mod.c
6. Compile module.mod.c → module.mod.o
7. Run modpost
8. Link objects → module.ko
9. Update Modules.order
10. Update Module.symvers
this makes our understanding clear on external module compilation
Kernel Module build flow:
module.c
↓
module.o
↓
module.mod.c
↓
module.mod.o
↓
modpost
↓
module.ko
↓
Modules.order updated
Module.symvers updated
this is an interview question so please dont ignore
Hope you are clear with linux kernel module internals, to conclude in this lecture we have learnt about how linux kenrel modules follow a structreud build process managed by the Kbuild system. so in build process source files are compiled, meta data files are generated, symbols are alidated, and modules are linked.
Files generated:
.mod.c
.mod.o
.ko
Modules.order
Module.symvers
this understanding will give you and edge to debug kenrel modules, understaing the symbol dependencies and work efficiently with linux kenrel internals.
Please follow our free linux kenrel development course for more tutorials.
Free Learning to all!!
EmbeddedPathashala.
