Modules by jgreddy30



Each piece of code that can be added to the kernel at runtime is called a „module‟. The linux
kernel offers support for quite a few different types of modules, including, but not limited to
device drivers

A module is „object code‟ (not linked to a complete executable) that can be dynamically linked
to the running kernel and can be unlinked

Modutils: insmod; rmmod; ksyms; lsmod; modinfo; modprobe; insmod_ksymoops_clean;
depmod; kerneld;

insmod: Installs a loadable module in the running kernel. Load time parameters can be passed to
the module, to customize its operation ( eg. I/O ports, IRQ Nos etc)

rmmod tries to unload a (set of ) module(s) from the running kernel with the restriction that
they are not in use and that they are not referred to by other modules.

Lsmod Shows information about all loaded modules.(name, size, use count, list of referring
modules etc..)

Modinfo: Displays information about a kernel module ( from object file)

modprobe Uses a “makefile”-like dependency file (created by „depmod‟) to automatically load
the relevant modules from the set of modules available in predefined directory trees.
Used to load a module, either a single module, a stack of dependent modules.
Will try to load a module out of a list and stops loading as soon as one module loads successfully

depmod     Makes a “Makefile”-like dependency file, which is later used by modprobe.

Kerneld: It is a user mode program with super user privilege to help the kernel itself to load and
unload the modules as they are needed

Module Initialization & Cleanup

#define MODULE
#include <linux/module.h>

int init_module(void) { printk(“<1>Hello World\n”); return 0;}
void cleanup_module(void) { printk(“<1> Goodbye\n”); }

You can test the module by calling insmod and rmmod (Note that only superuser can load and
unload a module).

root# gcc –c hello.c
root# insmod ./hello.o
Hello, World
root# rmmod hello

                          Linking a module to the kernel

                 Module                           Kernel Proper

   insmod        init_module( )
                                                       register_capability( ))

                                                          capabilities[ ]

                                                        printk( )

                  cleanup_module( ))
                   cleanup_module(                 unregister_capability( ))

     KEY                  One function                 Data     Function call           Data pointer
                           Multiple functions                       Function pointer
                                                                                       to data

Application vs Module

An application performs a single task from beginning to end.

A module registers itself in order to serve future requests and its “main” function i.e.,
init_module terminates immediately.

The second entry point of a module, “cleanup_module” gets invoked just before the module is
unloaded by rmmod etc.

A module is linked only to the kernel and the only functions it can call are the ones exported by
the kernel. A module is not linked to any standard library like libc etc.

Explicit Initialization and cleanup Functions

#include <linux/init.h>
module_ init (my_init);
module_exit (my_cleanup);

The advantage of doing things this way is that each initialization and cleanup function in the
kernel can have a unique name, which helps with debugging These functions also help for
writing drivers that work either as a module or built directly in the kernel.

Important Files: /proc/modules

Module Configuration Parameters

Several parameters that a driver needs to know can change from system to system. For instance,
the driver must know the hardware‟s actual I/O addresses, or memory range. Sometimes you
need to pass parameters to a driver to help it in finding its own device or to enable/disable
specific features. Depending on the evice, there may be other parameters in addition to the I/O
address that affects the driver‟s behaviour, such as device brand and release number. It is
essential for the driver to know the value of these parameters in order to work correctly.
Parameter values can be assigned at load time by insmod. The command accepts the
specification of integer and string values on the command line. Thus, if your module were to
provide an integer parameter called ival and a string parameter called sval, the parameters could
be set at module load time with an insmod command like:

       insmod hello.o ival=200 sval=”Welcome”

However, before insmod can change module parameters, the module must make them available.
Parameters are declared with the MODULE_PARM macro, which is defined in module.h.
MODULE_PARM takes two parameters: the name of the variable and a string describing its
type. The macro should be placed outside of any function and is typically found near the head of
the source file. The two parameters mentioned earlier could be declared with the following lines:

       int ival=0;
       char *sval;

       MODULE_PARM(ival, “i”);
       MODULE_PARM(sval, “s”);

Insmod will allocate the memory for the user supplied parameter and set the variable

Version Control in Modules

One of the main problems with modules is their version dependency. There is need to recompile
the module against the headers of each kernel version being used. Each module defines a symbol
called __module_kernel_version, which insmod matches against the version number of the
current kernel. The compiler will define the symbol for you whenever you include
<linux/module.h>. If you want to compile your module for a particular kernel version, you have
to include the specific header files for that kernel. A module is incompatible with a different
kernel version only if the software interface offered by the kernel has changed.
Driver writers must add some explicit support if their modules are to work with versioning.
Version control can be inserted in one of the two places, in the makefile or in the source itself.
The following compilation command is given to include new kernel include directory:

       gcc –c -DMODULE –D__KERNEL__ -nostdinc –I/usr/src/linux-2.4.4
The option –nostdinc tells the compiler not to include the standard headers.

Loading Modules on Demand

Linux offers support for automatic loading and unloading of modules
1. To avoid kernel memory by keeping drivers in core when they are not in use
2. To allow creation of „generic‟ kernels that can support a wide variety of hardware.

Any kernel space code can request the loading of a module when needed, by invoking a facility
known as kmod. To use kmod, include <linux/kmod.h> in your driver source.

To request the loading of a module, call request_module
     int request_module(const char *module_name);
The return value will be 0 for success, or one of the negative error codes if something goes

Exporting Symbols

A module implements its own functionality without the need to export any symbols. You will
need to export symbols, whenever other modules may benefit from using them. You may also
need to include specific instructions to avoid exporting all non-static symbols, as most versions
of modutils export all of them by default.
The Linux kernel header files provide a convenient way to manage the visibility of your
symbols, thus reducing namespace pollution and promoting proper information hiding.
If your module exports no symbols at all, you might want to make that explicit by placing a line
with this macro call in source file:
If you need to export a subset of symbols from your module, the first step is defining the
preprocessor macro EXPORT_SYMTAB. This macro must be defined before including
If EXPORT_SYMTAB is defined, individual symbols are exported with a couple of macros:
Either version of the macro will make the given symbol available outside the module; the second
version (EXPORT_SYMBOL_NOVERS) exports the symbol with no versioning information.

Creating stacked loadable modules

You can stack new modules on top of other modules, and new modules can use symbols
exported by your module. Module stacking is implemented in the main stream kernel sources as
well: each input USB device module stacks on the usbcore and input modules.
Module stacking is useful in complex projects. If a new abstraction is implemented in the form
of a device driver, it might offer a plug for hardware-specific implementations. For example,
stacking in the parallel port subsystem is shown below:

                Port sharing              operations                      Kernel API
                                                       parport_pc          Kernel API
                and device                             parport_pc         (Message
                                                                          printing, driver
                               parport                                    registration,
                                                                          port allocation,
           lp                                                             etc.)

When using stacked modules, modprobe utility is very useful to load any other required module.


To top