3 Linux Loadable Module
Traditionally under Unix ,  device drivers had to be linked with the kernel, and the system had to be brought down and then restarted after installing a new driver. Linux introduced the concept of a dynamically loadable driver called a module. Linux modules can be loaded or removed dynamically without requiring the system to be shut down. All Linux drivers can be written so that they are either of the statically linked type, or of the modular type which makes them dynamically loadable.    You can use the command  insmod to insert  a module into the kernel and rmmod to remove the module from the kernel. The example hello sample   shows how to insert and remove a module.  Let's  look at the makefile of the sample:

  1. INCLUDEDIR = /usr/src/linux/include
  2. CFLAGS = -D__KERNEL__ -DMODULE -O -I$(INCLUDEDIR)
  3. OBJS    = hello.o
  4. hello.o: hello.c
  5. load:
  6.         insmod hello.o port=0x300
  7. unload:
  8.         rmmod hello
  9. clean:
  10.         rm -f $(OBJS)
2    __KERNEL__ -- This code will be run in kernel mode, not as part of a user process.  
      MODULE        -- Appropriate definitions for a kernel module
5-6  load the module and pass the port address to the module.
7-8  unload the module from the kernel.  

Here is the code  snippet of  the hello.c:
  1. static int port = 0;
  2. MODULE_PARM(port, "i");
  3. int init_module(void)
  4. {
  5.   printk("<1>Hello, world\n");
  6.   printk("0x%x\n", port);
  7.   return 0;
  8. }
  9. void cleanup_module(void)
  10. {
  11.   printk("<1>Goodbye cruel world\n");
  12. }
3-8    The  init_module() function is called whenever a module is loaded into the kernel. This is the entry point of the module. This is similar to the main()  function of your C application  program. An insmod command  invokes init_module().  
9-12   The cleanup_module() function is the exit point of the module.  A rmmod invokes cleanup_module.

The macro MODULE_PARM in line 2, which  is defined in <linux/module.h>,  allows the assignment of  parameter values      at load time. Since I assigned the value of 0x300 to variable port in the Makefile, it will pass this value to the driver when I do make load.

It is important to note that printk() is different from printf(). The printk() function is defined in the kernel. It sends the output   to the console. This means you can not see the output of printk() while running X-windows.  Keep it in mind that you should   always debug a Linux  driver without running X-Windows.

To compile and load  the hello module into the kernel:
 1 - make  to compile the module.
 2-  make load to load the hello module into the kernel.

To verify if   the  module is properly loaded:
 [root@peanut /root]   less /proc/modules. On my PC, I have  the following:

serial                   18964   0
3c59x                  21512  1
aic7xxx               124452 3
sd_mod              16768   3
hello                    432      0  <-- This is our hello module

To unload the module from the kernel:
 [root@peanut /root]  make unload
 [root@peanut /root] less /proc/modules to verify the module is unloaded. 

serial                   18964   0
3c59x                  21512  1
aic7xxx               124452 3
sd_mod              16768   3

Under Linux, all information about the kernel is stored in the /proc filesystem . Most of the files under /proc are read-only. For more information about the /proc filesystem, you can read the man page; it clearly explains the /proc filesystem.


 Previous                       Index                                     Next