Showing posts with label modules. Show all posts
Showing posts with label modules. Show all posts

Saturday, July 19, 2008

Compiling and Inserting the First Kernel Module

Let’s now see how to compile the module program shown in previous post. We shall write a Makefile to make the procedure of compilation simpler. Below is a ‘template’ of a Makefile, which I use to compile my modules. The description follows.

########################################################################################

#Build as a loadable module
obj-m += ‘module_name_1’.o ‘module_name_2’.o
‘module_name_1’-objs := “space separated list of object files needed by ‘module_name_1’.o”
‘module_name_2’-objs := “space separated list of object files needed by ‘module_name_2’.o”

#Location of the current linux kernel source directory
SRC=/lib/modules/`uname -r`/build

#Working Directory
PWD=`pwd`

default:
make -C ${SRC} M=${PWD} modules

clean:
rm -f ${‘module_name’-objs}‘module_source_name.o ‘module_name’.ko ‘module_name’.mod.o
rm -f ‘module_name’.mod.c

################################################################################

obj-m tells the compiler which object files have to be created on make command. As many modules can be specified here, as we want to create. After that, for each module in obj-m list, a list of object files has to be specified which together link into that particular module’s object file.

Under /lib/modules, there is one subdirectory for each kernel installed in your system, with the name of that particular kernel. Each of these directories contain source (code, module object files) of the corresponding kernel image. The shell command uname -r gives as output the name of the currently running kernel. Therefore, SRC environment variable stores the path to the skeleton of source code of currently running kernel.

This path is specified to let make read the kernel top level Makefile, which defines the rules to make the target, i.e. modules. This environmental variable can alternatively/additionally be passed at command line, as an argument to make. As is the case with Makefiles, SRC specified at command line will take precedence over the one specified in Makefile.
The -C switch in make changes the current directory to $SRC (kernel source directory) to find kernel top level Makefile. M=dir specifies the directory where the module to be built is present. M=dir modules instructs to make all those modules in the directory dir, listed in variable obj-m.

The myFirstModule Makefile:


#####################################################################################

#Build as a loadable module
obj-m += myFirstModule.o
myFirstModule-objs:= myFirstModuleSource.o

#Location of the linux source directory
SRC=/lib/modules/`uname -r`/build

#Working Directory
PWD=`pwd`

default:
make -C ${SRC} M=${PWD} modules

clean:
rm -f ${ myFirstModule-objs} myFirstModule.o myFirstModule.ko myFirstModule.mod.o
rm -f myFirstModule.mod.c

###############################################################################


Running make:
[shweta@localhost modules]# make
make -C /lib/modules/`uname -r`/build M=`pwd` modules
make[1]: Entering directory `/usr/src/kernels/2.6.9-42.EL-smp-i686'
CC [M] /home/Shweta/wikalk/modules/myFirstModuleSource.o
LD [M] /home/Shweta/wikalk/modules/myFirstModule.o
Building modules, stage 2.
MODPOST
CC /home/Shweta/wikalk/modules/myFirstModule.mod.o
LD [M] /home/Shweta/wikalk/modules/myFirstModule.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.9-42.EL-smp-i686'


Inserting (or linking) the module:
The shell provides two commands to insert a module into the kernel, insmod and modprobe, which both do the same set of activities. The difference lies in how they search for the module binary to load.

insmod requires the absolute path of the module as argument:
[shweta@localhost modules]# insmod /root/wikalk/modules/myFirstModule.ko
modprobe requires just the module name as argument:

[shweta@localhost modules]#modprobe myFirstModule
The modprobe searches for the module name in the default path /lib/modules/`uname -r`. If no module with the given name is found, an error is displayed.

So now, our myFirstModule is inserted/removed as follows:
[shweta@localhost modules]#insmod myFirstModule.ko
Hey! myFirstModule is in the kernel now.

[shweta@localhost modules]#rmmod myFirstModule
myFirstModule is removed from kernel
myFirstModule was in kernel for 143 seconds.

Some Points to Remember:

  • After inserting a module, it needs to be explicitly unloaded or else it will be removed when the system is shut down. However, it is a better way to explicitly unload the module if it no more required otherwise it will consume system resources (memory, CPU...) for no use.
  • If the return statement is missing in init() function, the compilation succeeds without any errors or warnings. But insmod gives “error inserting myFirstModule.ko

Wednesday, June 25, 2008

The OS, The Kernel and The Modules

Typically kernel literature start with the words like modules, microkernels etc. Lets quickly run over these to set the context right for reading.

Often the terms operating system and kernel are confused because the two terms are used interchangeably in many books. But actually there is a difference: kernel is just one part of operating system, other parts being device drivers, user interface etc. Kernel is the innermost layer and UI is the outermost layer of an operating system. For example, command shell is a part of operating system, not of kernel. When the ls command is fired on the shell, it invokes kernel routines to read the contents of a particular directory. The kernel manages all the data structures and functions which are needed by the operating system (and the applications running on it) for several purposes. For another example, bootstrap loader is a part of operating system, which loads the kernel into RAM at the system startup. Applications such as web browser or document viewer are NOT part of operating system, however they are installed by default with many operating systems (ms-windows, red hat).

The kernel as described in Linux Kernel Development by Robert Love is as follows. "The kernel is the core internals of the operating system; the software that provides "basic services" for all other parts of the system, manages hardware, and distributes system resources. Typical components of a kernel are interrupt handlers to service interrupt requests, a scheduler to share processor time among multiple processes, a memory management system to manage process address spaces, and system services such as networking and interprocess communication."

So now we know, that the core functionality of an operating system is provided by its kernel.

Now what are modules when we talk about linux kernel? Before understanding the concept of the module, one needs to understand that by design, linux is a monolithic kernel. A monolithic kernel is implemented as a single large process. It loads into memory as a whole, executing everything in kernel mode.
The another category is microkernel architecture, in which the kernel only includes core essential functionality like inter-process communication, process scheduling, synchronization (the term microkernel: minimal kernel). The services such as memory management, device drivers are run as separate processes, which run in user space on top of the microkernel.

Compare the two architectures:
  • Monolithic kernels give great performance, with simple design, having trivial communication within the kernel (direct function calls as in a single program). But the problem with this design is that one small failure in any part of the code brings the entire system down.
  • Microkernel architectures propose clean interfaces, hardware independence, and better memory management because everything is implemented as separate components. This also makes development easy. Moreover, in case of a problem, only the specific component fails, other parts function properly. But the problem is that communication within the kernel is done by means of message passing, which makes the performance very poor.
The concept of module fits somewhere between these two kernel designs. In order to achieve advantages of microkernel architecture, offering monolithic performance at the same time, the linux kernel divides its services into modules. Different filesystems, device drivers, memory management etc are separate modules which can be inserted or removed from kernel at run time, i.e. without even having to compile the kernel. For example, ext3, vfat filesystems are inserted into the kernel as modules. After inserting into the kernel, the module becomes a part of the kernel and executes in kernel mode like other kernel routines. (While in microkernel design, it would execute as a separate process in user mode).
Try shell command lsmod to list down all the modules currently linked into the kernel.
The feature of modules in linux kernel offers a great flexibility to linux programmers and independent hackers to develop their own modules with their customized functionalities. For learners, experimenting with the kernel becomes as easy as wiriting a normal C code. If there were no modules, even for a smallest addition/experiment, one would have to make changes directly into main kernel code. Modules give us freedom to develop the kernel even without touching the kernel. Thats one of the greatest opportunities Linux has given to the kernel freaks.

Thats all the theory before starting kernel programming. From now on, only practicals. In the next post, I shall tell how did I write a small, useless module and run it in the kernel. Stay Tuned!!

References:
  1. The Tanenbaum-Torvalds Debate.
  2. The Linux Kernel Module Programming Guide.