An introduction to Linux Device Drivers - #1

Today we’ll be discussing a basic c code, the famous hello.c, which will be loaded as a kernel module and discuss some of the basic aspects related to it.

include

include

MODULE_LICENSE (“GPL”); // included in module.h, tells about the license the code is having.

static int _init helloinit (void)

{

printk (KERN_ALERT “Hello, worldn”);

return 0;

}

static void _exit helloexit (void)

{

printk (KERN_ALERT “Goodbyen”);

}

moduleinit (helloinit);     // hello_init is the initialization function

moduleexit (helloexit);     //hello_exit is the exit function

The header* * contain various declarations and definitions related to the loading and cleaning up of modules. The macros moduleinit and moduleexit are declared in the . The argument functions passed to module_init( ) and module_exit( ) are executed at the loading and unloading times respectively of a module. The initialization function, basically, sets up the device to be used later. The exit function cleans up the device ( opposite to initialization).

Now coming to the* _init* and *exit* terms used in the code. The _init in static int _init helloinit (void) specifies that the helloinit function is executed only at module load time. The module loader drops the initialization function for other uses once the module is loaded. The initialization function better be static since they are not meant to be visible outside the specific file ( not mandatory though). Similar explanation goes for _exit. This makes the exit function executed only at exit time.

The printk function, at a first glance, might look identical to printf of , but printk lets you set priority levels for the message, like KERNALERT, KERNINFO, etc. We’ll discuss about them later.

How to compile the code and execute it. Let us assume that you named the source file above as hello.c. Use any suitable text editor to write a Makefile as below :

obj-m    += hello.o

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

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
rm -f *~

I hope you have the kernel source in your system. If not you can get the kernel source from kernel.org. If you are using Fedora, you can do:

# yum install kernel-devel

To compile, in the current directory ( where there is hello.c and the Makefile) do :

$ make

Then change to super user by : $su

and do : # insmod ./hello.ko

If you do : # tail -f /var/log/messages (You can open this in a separate terminal to view the system logs)

then you will be able to see a line saying “Hello, world”. This is what your hello_init( ) was supposed to do at module load time. You can also see the module name “hello” among the list of loaded modules doing lsmod. Now you can unload the module do :

# rmmod hello

Now in /var/log/messages, you will see “Goodbye”. This is due to hello_exit( ).

continued …

Check the next post: Wrote a patch for kettu, web interface for transmssion »

Share on:
comments powered by Disqus