Friday 28 June 2013

[Kernel Programming: #1] Introduction to Kernel Programming

Will share Kernel Programming concepts in couple of days :)

Day 1: Load and remove a simple module to/from Kernel.

A module is a loadable Kernel object - related subroutines, data are grouped together, it has one entry and one exit point. It enables the dynamic insertion/removal of drivers into/from the Kernel on demand in response to the device state.

Linux Kernel supports the insertion and removal a module at runtime based on the requirement or demand.

Module has one entry point and one exit point, these are functions.
The entry point (start function) will be called when the module is loaded into kernel successfully.
The exit point will be used for releasing the resources which are acquired in related subroutines, and exit point is called just before when the module is removed from Kernel.

Entry point: int init_module(void); --> Initialization function: Module execution will be start at this point. This is entry function for modules like main() for C programs.
Exit point: void cleanup_module(void); --> Cleanup function: Modules end by calling this function.

Example: module_1.c

  1 #include<linux/module.h> /* Needed by all modules *MUST* */
  2
  3 int init_module(void) {
  4         printk(KERN_ALERT "1st module program: Module Inserted\n");
  5         return 0;
  6 }
  7
  8 void cleanup_module() {
  9         printk(KERN_ALERT "1st module program: Module Removed\n");
 10 }

We can put our own names for start and cleanup functions, but it requires other macros should be used in the code. I will explain it later.

Start function init_module() will register a handler with Kernel to perform a task.
And, cleanup_module() will release all resources, so that the module can unload safely from Kernel.

Every kernel module must include <linux/module.h>, tells that it is a module.
printk() function is used as logging mechanism for kernel which basically store the information and log any warning/error msgs for debugging purpose.
And, printk() takes the priority of the message and message as arguments.
The priority levels are available in <linux/kernel.h>. So, it is advised to include this macro also in the program.
I set KERN_ALERT as priority (1, highest) for our message, so that printk will print the msg in user console. If the priority is low then it may logged into /var/log/messages.

Compiling the Kernel module:
We use makefiles in order to build the kernel modules.
Will update the makefile details soon.
Makefile to compile our module.

  1 obj-m += module_1.o
  2
  3 KDIR = /usr/src/linux-headers-2.6.32-28-generic
  4
  5 all:
  6         $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
  7
  8 clean:
  9         rm -rf *.o *.ko *.mod.* *.symvers *.order


Since I have named module_1.c for our module, the object file which is generated after compilation will be module_1.o. See 1st line in Makefile.

At line 3, KDIR is the location of our kernel header files directory . You can get these details by using the command "uname -r". After using this command you will get the result like (2.6.32-28-generic). And use "ls /usr/src/", here we find a directory named like linux-headers-2.6.32-28-generic.

At line 5, all used to build the kernel module, we input the location of kernel header files directory in order to build our module.
And, clean is used to remove all executable files after we unload our module from Kernel.

Build the module:
Just run "make", you will see msg like below

make -C /usr/src/linux-headers-2.6.32-28-generic SUBDIRS=/home/***/module_programming/module1 modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-28-generic'
  CC [M]  /home/***/module_programming/module1/module_1.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/***/module_programming/module1/module_1.mod.o
  LD [M]  /home/***/module_programming/module1/module_1.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-28-generic'

So, our module is build without any errors.
Now use below commands to load/unload the module to/from kernel.
Step1. insmod module_name.ko
    --> used to load our module into the kernel
Step2. dmesg
  --> used to see the printk log details.
Step3. rmmod module_name.ko
   --> used to remove our module from kernel

After insmod, enter dmesg then we will see our msg on the terminal, which we added in printk() function. And also again rmmod command, check log using dmesg.

Note: we will see the below error when insmod is used 
>> insmod: error inserting 'module_1.ko': -1 Operation not permitted
Then, use "sudo -s" command to work in root mode, we won't see this error msg again.

If we have multiple files for a module then the makefile looks like below

obj-m += module_temporary_name.o
module_temporary_name-objs := module_1.o module_2.o

all and clean are same as mentioned above.

No comments:

Post a Comment

You might also like

Related Posts Plugin for WordPress, Blogger...