Loading a Module
Figure: The List of Kernel Modules
There are two ways that a kernel module can be loaded.
The first way is to use the insmod command to manually insert the
module into the kernel.
The second, and much more clever way, is to load the module as it is needed; this
is known as demand loading.
When the kernel discovers the need for a module, for example when the user mounts
a file system that is not in the kernel, the kernel will request that the kernel daemon
(kerneld) attempts to load the appropriate module.
The kernel daemon is a normal user process albeit with super user privileges.
When it is started up, usually at system boot time, it opens up an Inter-Process
Communication (IPC) channel to the kernel.
This link is used by the kernel to send messages to the kerneld asking for
various tasks to be performed.
Kerneld's major function is to load and unload kernel modules but it is also
capable of other tasks such as starting up the PPP link over serial line when it
is needed and closing it down when it is not.
Kerneld does not perform these tasks itself, it runs the neccessary programs
such as insmod to do the work.
Kerneld is just an agent of the kernel, scheduling work on its behalf.
The insmod utility must find the requested
kernel module that it is to load.
Demand loaded kernel modules are normally kept in /lib/modules/kernel-version.
The kernel modules are linked object files just like other programs in the system
except that they are linked as a relocatable images.
That is, images that are not linked to run from a particular address.
They can be either a.out or elf format object files.
insmod makes a privileged system call to find the kernel's exported symbols.
These are kept in pairs containing the symbol's name and its value, for example its
The kernel's exported symbol table is held in the first module data structure
in the list of modules maintained by the kernel and pointed at by the module_list
Only specifically entered symbols are added into the table, which is built when the
kernel is compiled and linked, not every symbol in the kernel is exported to
An example symbol is ``request_irq'' which is the kernel routine that must
be called when a driver wishes to take control of a particular system interrupt.
In my current kernel, this has a value of 0x0010cd30.
You can easily see the exported kernel symbols and their values by looking at
/proc/ksyms or by using the ksyms utility.
The ksyms utility can either show you all of the exported kernel symbols or only
those symbols exported by loaded modules.
insmod reads the module into its virtual memory and fixes up its unresolved
references to kernel routines and resources using the exported symbols from the
This fixing up takes the form of patching the module image in memory.
insmod physically writes the address of the symbol into the appropriate
place in the module.
When insmod has fixed up the module's references to
exported kernel symbols,it asks the kernel for enough space to hold
the new kernel, again using a privileged system call.
The kernel allocates a new module data structure and enough
kernel memory to hold the new module and puts it at the end of the kernel modules list.
The new module is marked as UNINITIALIZED.
Figure 12.1 shows the list of kernel modules after two
modules,VFAT and VFAT have been loaded into the kernel.
Not shown in the diagram is the first module on the list, which is a pseudo-module that is only
there to hold the kernel's exported symbol table.
You can use the command insmod to list all of the loaded
kernel modules and their interdependencies.
lsmod simply reformats /proc/modules which is built from the list of kernel
module data structures.
The memory that the kernel allocates for it is mapped into the insmod process's
address space so that it can access it.
insmod copies the module into the allocated space and relocates it so
that it will run from the kernel
address that it has been allocated.
This must happen as the module cannot expect to be loaded at the same address
twice let alone into the same address in two different Linux systems.
Again, this relocation involves patching the module image with the appropriate
The new module also exports symbols to the kernel and
insmod builds a table
of these exported images.
Every kernel module must contain module initialization and module cleanup
routines and these symbols are deliberately not exported but insmod must
know the addresses of them so that it can pass them to the kernel.
All being well, insmod is now ready to initialize the module and it makes
a privileged system call passing the kernel the addresses of the module's initialization
and cleanup routines.
When a new module is added into the kernel, it must update the kernel's set of symbols
and modify the modules that are being used by the new module.
Modules that have other modules dependent on them must maintain a list of references
at the end of their symbol table and pointed at by their module data structure.
Figure 12.1 shows that the VFAT file system module is dependent on the
FAT file system module.
So, the FAT module contains a reference to the VFAT module; the reference
was added when the VFAT module was loaded.
The kernel calls the modules initialization routine and, if it is successful it
carries on installing the module.
The module's cleanup routine address is stored in it's module data structure and
it will be called by the kernel when that module is unloaded.
Finally, the module's state is set to RUNNING.