Project: Hellomod


This section introduces the basic concepts necessary to understand other Linux concepts and structures discussed later in the book. Our projects center on the creation of a loadable module using the new 2.6 driver architecture and building on that module for subsequent projects. Because device drivers can quickly become complex; our goal here is only to introduce the basic constructs of a Linux module. We will be developing on this driver in later projects. This module runs in both PPC and x86.

Step 1: Writing the Linux Module Skeleton

The first module we write is the basic "hello world" character device driver. First, we look at the basic code for the module, and then show how to compile with the new 2.6 Makefile system (this is discussed in detail in Chapter 9), and finally, we attach and remove our module to the kernel using the insmod and rmmod commands respectively:[5]

[5] Be sure to have module unloading enabled in your configuration.

 ----------------------------------------------------------------------- hellomod.c 001 // hello world driver for Linux 2.6 004  #include <linux/module.h> 005  #include <linux/kernel.h> 006  #include <linux/init.h> 007  #MODULE_LICENCE("GPL"); //get rid of taint message 009  static int __init lkp_init( void ) {   printk("<1>Hello,World! from the kernel space...\n");   return 0; 013  } 015  static void __exit lkp_cleanup( void ) {   printk("<1>Goodbye, World! leaving kernel space...\n"); 018  } 020  module_init(lkp_init); 021  module_exit(lkp_cleanup); ----------------------------------------------------------------------- 

Line 4

All modules use the module.h header file and must be included.

Line 5

The kernel.h header file contains often used kernel functions.

Line 6

The init.h header file contains the __init and __exit macros. These macros allow kernel memory to be freed up. A quick read of the code and comments in this file are recommended.

Line 7

To warn of a possible non-GNU public license, several macros were developed starting in the 2.4 kernel. (For more information, see modules.h.)

Lines 912

This is our module initialization function. This function should, for example, contain code to build and initialize structures. On line 11, we are able to send out a message from the kernel with printk(). More on where we read this message when we load our module.

Lines 1518

This is our module exit or cleanup function. Here, we would do any housekeeping associated with our driver being terminated.

Line 20

This is the driver initialization entry point. The kernel calls here at boot time for a built-in module or at insertion-time for a loadable module.

Line 21

For a loadable module, the kernel calls the cleanup_module() function. For a built-in module, this has no effect.

We can have only one initialization (module_init) point and one cleanup (module_exit) point in our driver. These functions are what the kernel is looking for when we load and unload our module.

Step 2: Compiling the Module

If you are used to the older methods of building kernel modules (for example, those that started with #define MODULE), the new method is quite a change. For those whose 2.6 modules are their first, this might seem rather simple. The basic Makefile for our single module is as follows:

 Makefile 002 # Makefile for Linux Kernel Primer module skeleton (2.6.7) 006   obj-m += hellomod.o 

Notice that we specify to the build system that this be compiled as a loadable module. The command-line invocation of this Makefile wrapped in a bash script called doit is as follows:

 ----------------------------------------------------------------------------doit 001 make -C /usr/src/linux-2.6.7 SUBDIRS=$PWD modules -------------------------------------------------------------------------------- 

Line 1

The C option tells make to change to the Linux source directory (in our case, /usr/src/linux-2.6.7) before reading the Makefiles or doing anything else.

Upon executing ./doit, you should get similar to the following output:

 Lkp# ./doit make: Entering directory '/usr/src/linux-2.6.7'    CC [M]  /mysource/hellomod.o    Building modules, stage 2    MODPOST    CC  /mysource/hellomod.o    LD [M]  /mysource/hellomod.ko   make: Leaving directory '/usr/src/linux-2.6.7'   lkp# _ 

For those who have compiled or created Linux modules with earlier Linux versions, notice that we now have a linking step LD and that our output module is hellomod.ko.

Step 3: Running the Code

We are now ready to insert our new module into the kernel. We do this using the insmod command, as follows:

 lkp# insmod hellomod.ko 

To check that the module was inserted properly, you can use the lsmod command, as follows:

 lkp# lsmod Module     Size  Used  by hellomod    2696  0   lkp# 

The output of our module is generated by printk(). This function prints to the system file /var/log/messages by default. To quickly view this, type the following:

 lkp# tail /var/log/messages 

This prints the last 10 lines of the log file. You should see our initialization message:

 ... ... Mar  6 10:35:55  lkp1  kernel: Hello,World! from the kernel space... 

To remove our module (and see our exit message), use the rmmod command followed by the module name as seen from the insmod command. For our program, this would look like the following:

 lkp# rmmod hellomod 

Again, your output should go to the log file and look like the following:

 ... ... Mar  6 12:00:05  lkp1  kernel: Hello,World! from the kernel space... 

Depending on how your X-system is configured or if you are at a basic command line, the printk output should go to your console, as well as the log file. In our next project, we touch on this again when we look at system task variables.




The Linux Kernel Primer. A Top-Down Approach for x86 and PowerPC Architectures
The Linux Kernel Primer. A Top-Down Approach for x86 and PowerPC Architectures
ISBN: 131181637
EAN: N/A
Year: 2005
Pages: 134

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net