FreeOS.com logo

FreeOS Most Popular
* Most Read stories
* Commented Stories
* Active Categories
* Non Linux Section
* User Submitters
* Top Polls
* Top Authors
* Top Reviews
* Top Rated
* Top Search Terms

Top Articles
* Writing a Linux device driver
* The Linux filesystem explained
* Samba NT Domain Controller
* Setting up Squid as your caching HTTP/FTP proxy
* Web server tutorial - Part 1

FreeOS Highlights
* Howtos (72)
* Reviews (20)
* Opinions (18)
* Interviews (8)
* News (3)

My FreeOS

Nick:
Pass:
Register

Forgot your password?

Contact Us
Contact Us

       

Project: Linux triangle Articles triangle

Introduction to Linux kernel modules

By Vans Information <Content@vansinfo.com>
Posted: ( 2001-05-16 07:56:03 EST by gatha )

The earlier articles touched on what Linux Operating System is all about. You know its scope, its advantages, disadvantages, weaknesses and strongholds. In this article, we take a closer look at the Kernel modules--one of the two modes that Linux operates in.

Linux operates in two modes--the Kernel mode (kernel space) and the User mode (user space). The kernel works in the highest level (also called supervisor mode) where it has all the authority, while the applications work in the lowest level where direct access to hardware and memory are prohibited. Keeping in line with the traditional Unix philosophy, Linux transfers the execution from user space to the kernel space through system calls and the hardware interrupts. The Kernel code executing the system call works in the context of the process, which invokes the system call. As it operates on behalf of the calling process, it can access the data in the processes address space. The kernel code that handles interrupts, works to the processes and related to any particular process.

Linux Kernel Modules

The Linux kernel is a monolithic kernel i.e. it is one single large program where all the functional components of the kernel have access to all of its internal data structures and routines. The alternative to this is the micro kernel structure where the functional pieces of the kernel are broken out into units with strict communication mechanism between them. This makes adding new components into the kernel, via the configuration process, rather time consuming. The best and the robust alternative is the ability to dynamically load and unload the components of the operating system using Linux Kernel Modules.

The Linux kernel modules are piece of codes, which can be dynamically linked to the kernel (according to the need), even after the system bootup. They can be unlinked from the kernel and removed when they are no longer needed. Mostly the Linux kernel modules are used for device drivers or pseudo-device drivers such as network drivers or file system. When a Linux kernel module is loaded, it becomes a part of the Linux kernel as the normal kernel code and functionality and it posses the same rights and responsibilities as the kernel code.

Life cycle of Linux kernel module

The life cycle of a module starts with the init_module(). The task of init_module is to prepare the module for later invocation. The module is registered to the kernel and attaches its data-structures and functionality to the kernel. The kernel-defined external functions are also resolved. The life cycle of the module ends with cleanup_module(). It `unregisters' the module functionality from the kernel. We shall later take a more detailed look at the life cycle of the module.

Simple Module Program

Let us now program a simple module to review its life cycle. The init_module is called when the module is inserted into the kernel where as the cleanup_module is called just before removing it from the kernel. In the following program, the init_module and the cleanup_module functions are demonstrated.

/* Simple Linux kernel module Feb'2001

#include
#include

#if CONFIG_MODVERSIONS==1
#define MODVERSINS
#include

#endif

/ initialise the module /
int init_module()
{
printk("init_module invokedn");
printk("the message is printed from the kernel spacen");

/ if the non zero value is returned, then it means that the init_module failed and the kernel module can't be loaded /

return 0;
}

/ cleanup / end of module life cycle */
void cleanup_module()
{
printk("cleanup_module invokedn");
printk("module is now going to be
unloaded from the kerneln");
}

Compile the above program using the following:

#gcc -Wall -DMODULE -D__KERNEL__ -DLINUX -O -c simpelModule.c

Run the compiled module using the following:
#insmod simpleModule.o

Remember, you have to run the above command from the Linux shell at raw console (not from the console in Xwindows environment) at root login.

Now check the status of the module using
#lsmod

Then remove the module using #rmmod simpleModule

If you have not seen any of the module-initiated console printing (implemented using `printk') about the status of the module, use the following command to see the kernel messages. dmesg | less In the above, commands insmod, lsmod and rmmod are used to load and unload modules to the Linux kernel. The details are discussed in the following section.

Loading modules insmod loads the `loadable kernel modules' in the running kernel. insmod tries to link a module into the running kernel by resolving all the symbols from the kernel's exported `symbol table'.

Lets now discuss the demand loading of the module by the kernel, dynamically. When the Linux kernel discovers the need for a module, the kernel requests to the kernel daemon (kerneld) to load the appropriate module. To illustrate this with an example, lets mount a NTFS partition in the Linux system. If the NTFS filesystem support is not statically implemented in the kernel (but compiled as a module), the kernel daemon will search for the appropriate module and load it from the repository. Then the partition is mounted for the use.

Lets go deep into the action of the kernel daemon (kerneld). The kerneld is the normal user process having exclusive superuser privileges. At the time of booting, kerneld opens the IPC channel to the kernel and uses it for transferring messages (request for loading modules), to and from the kernel. While loading the module, the kerneld calls modprobe and insmod to load the required module. The insmod utility should able to access the requested module. The demand loadable kernel modules are usually located at /lib/module/ directory as the object files linked as relocatable images.

Let us revisit the working of the insmod to get a clear picture of the module loading operation. The insmod depends on some critical system calls to load the module to the kernel. It uses the sys_create_module to allocate kernel memory to hold module. It uses get_kernel_syms system call to get the kernel symbol table in order to link the module. It then calls the sys_init_module system call to copy the relocatable object code of the module to the kernel space. And soon after this, insmod calls the initialization function of the concerned module i.e. init_module. All of these system calls can be found in kernel/module.c.

Unloading modules

The modules can be unloaded using rmmod command. While removing modules, rmmod ensures the restriction that the modules are not in use and they are not referred by any other module or the part of the kernel. The demand loaded modules (i.e. the modules loaded by kerneld) are automatically removed from the system by `kerneld' when they are no longer used. Every time it's idle, timer expires and kerneld makes a system call requesting for all the demand loaded kernels, which are not busy to be removed. The modules, whose visited flags are cleared and marked as AUTOCLEAN, are `unloaded'.

Assuming that the module can be unloaded, the cleanup_module function of the concerned module is called to freeup the kernel resources it has allocated. After the successful execution of the cleanup_module, the module datastructure is marked DELETED and it is unlinked from the kernel and unlisted from the list of kernel modules. The reference list of the modules on which it (module removed) is dependent is modified and dependency is released. The kernel memory allocated to the concerned module is deallocated and returned to the kernel memory spool.

Version Dependency of modules Version dependency of the module is one of the trickiest parts of the Linux Kernel Module programming. Typically, the modules are required to be compiled for each version of the kernel. Each module defines a symbol called kernel_version, which insmod matches against the version number of the current kernel. The current kernel 2.2.x/2.4.x define the symbol in . Hence if the module is made up of multiple source files, the should be included in only one of the source files.

Though typically, modules should be recompiled for each kernel version, it is not always possible to recompile module when it is run on as a commercial module distributed in binary form. Kernel developers have provided a flexible way to deal with the version problem. The idea is that a module is incompatible with a different kernel version only if the software interface offered by the kernel is changed. The software interface is represented by the function prototype and the exact definition of all the data structures involved in the function call. The CRC algorithm can be used to map all the information about software interface to the single 32bit number. The issue of version dependency is handled by using the name of the each symbol exported.

Other articles by Vans Information

Current Rating: [ 7.2 / 10 ] Number of Times Rated: [ 122 ]

More Articles
* Know Linux
* If I could re-write Linux
* Interview with Mozilla engineering director Chris Hofmann
* Response to SCO's Open Letter
* GNU Linux Security

Contents
Articles
  Howtos
  Interviews
  News
  Opinions
  Reviews
Comparison
Links
  Articles
  Howtos
  Interviews
  Opinions
  Reviews
  Websites
News

Linux
About Linux

Print It!
Printer Friendly Version