Embedded Systems – Linux Kernel Module Programming

 

“Do you pine for the nice days of Minix-1.1, when men were men and wrote their own device drivers ?” – Linus Torvalds

 

What is a Kernel Module ?

Modules are pieces of code that can be loaded and unloaded into the Kernel upon demand. Now, we get to the real action, where a single wild pointer can wipe out your file system. One type of module is the device driver, which allows the Kernel to access to access hardware connected to the system.

Basic Terminologies

  • Char Device : Is the one with which the driver communicates by sending and receiving single characters. We will be mostly covering Char devices. Example – Serial, Parallel Ports, Sound Cards.
  • Block Device : Is the one with which the driver communicates by sending entire blocks of data.
  • Header Files : In order to have definitions of common structures and declarations be consistent across source files, it is easiest if these be in some sort of a central file that are included via ‘ # include’. You must have noticed Header files with the extension ‘.h’ in Arduino libraries. You may point out that you even noticed a few ‘.cpp’ files. A  header ‘.h’ file is where you declare your functions, classes, variables whereas a ‘.cpp’ file is where you define those previously declared elements.
  • Object File : A ‘.o’ file which is created by the compiler for every source file, before lining them together, into executable file. ‘.ko ‘ file is your object file linked with some kernel automatically generated structures that are needed by the kernel.
  • Makefiles : Assume you have a huge codebase that has hundreds of files with lots of dependencies. Following are the steps you will need to perform :

 

Hundreds of Files
|
 Compile each of them 
|
 Generate an Object File 
|
 Link all .o files to generate executable code
|
 If you do a small change in a file 
|
 Then you need to recompile and link all of them again

            Makefiles ensure that only the files that have been modified since the last build and those which are dependent are changed. It contains a file containing a set of rules to compile specific programs.

How do Modules get into the Kernel ?

  • Insmod : Insmod is a user space utility to load a module into Linux Kernel. It is a small program to intimate the Kernel that a module is attempted to be loaded and transfers the control to the Kerenl.
  • lsmod : To check whether the module is installed correctly. Type this command to see a list of modules installed on your system.

screenshot-from-2016-10-19-14-34-59

  • rmmod : To remove the  module.

There are various other terms associated like depmod, modprobe which will be covered as we proceed further.

 

figure_2_linux_device_driver_partition

 

_init and _exit

  • Module_init : It indicates when the particular function is used.
  • Module_exit : Exits and all the address space ( text, symbol ) used can be reclaimed.

Printk()

It is a function that prints a message. It is very similar to the wel know printf apart from the fact that it onlt works inside the kernel. You won’t see the message in user space, but to do that we use the ‘dmesg’ which prints the message buffer of the kernel.

Module License

MODULE_LICENSE(” Dual BSD/GPL “);

It allows loadable kernel modules to declare their licences to the world. The purpose is to let the kernel developer know when a non free module has been into a given kernel.

Modeversioning

A module compiled for one kernel won’t load if you boot a different kernel unless you enable CONFIG_MODEVERSIONS.

Writing you first Hello World

 

Hello World – Part 1 ( hello-1.c)

 

# include <linux/module.h>   /* Needed by all modules */
# include <linux/kernel.h>   /* Needed for kernel info */

int init_module(void)
  {
     printk(KERN_INFO " Hello World\n ");
     return 0;  /* A non zero return means init_module failed; can't be loaded */
  }

void cleanup_module(void)
  {
     printk(KERN_INFO " Goodbye World\n ");
  }

Compiling Kernel Modules

obj -m += hello.o   ( Generating the makefile )

All :

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

You need to compile the module using the same kernel that you’re going to load and use the module with.

Discussion

Kernel modules must have at least two functions : a “start” (initialization) function called init_module () which is called when the module is insmoded into the kernel , and an “end” (cleanup) function cleanup_module() which is called just before it is rmmoded. You can use any start or end function name which we will see in the coming tutorials.

What is KERN_INFO ?

There are eight possible loglevel strings, defiend in the header file :

  1.  KERN_EMRG : Used for emergency messages, usually those that precede a crash.
  2.  KERN_ALERT : A situation requiring immediate action.
  3.  KERN_CRIT : Critical conditions, for serious hardware or software problems.
  4.  KERN_ERR : Used to report error conditions.
  5.  KERN_WARNING : Warnings about problematic situations that do not create serious problems witht the system.
  6.  KERN_NOTICE : Situations that are normal but worthy to note.
  7.  KERN_INFO : Informational messages.
  8.  KERN_DEBUG : Used for debugging messages.

 

I hope you found this tutorial useful. If you have any doubt, feel free to ask.

Saumitra Kapoor

Leave a Reply

Bitnami