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 <linux/init.h>

#include <linux/module.h>

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

static int __init hello_init (void)


printk (KERN_ALERT “Hello, world\n”);

return 0;


static void __exit hello_exit (void)


printk (KERN_ALERT “Goodbye\n”);


module_init (hello_init);     // hello_init is the initialization function

module_exit (hello_exit);     //hello_exit is the exit function

The header <linux/init.h> contain various declarations and definitions related to the loading and cleaning up of modules. The macros module_init and module_exit are declared in the <linux/init.h>. 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 hello_init (void) specifies that the hello_init 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 <stdio.h>, but printk lets you set priority levels for the message, like KERN_ALERT, KERN_INFO, 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

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

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 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 <enter>

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 …

Resolved ATI issue in Fedora

System Specifications :

hp compaq 6515b,business series

processor-AMD Turion 64 X2 Dual-Core Mobile Technology
tl-50,clk rate 1600 mhz
hardisk -80gb
ram -1.5gb
Video card features  ATI Radeon X1250
Video Memory Shared video memory (UMA)
Max Allocated RAM Size 512.0 MB

Issues :

Problem with the Graphical User Interface. System used to hang a lot. Moving and clicking with the mouse was a pain. Even there was a latency to browse the application menu. Firefox won’t run nicely. System usage was normal. System ran fine in CLI.

Suspected problem : Lack of ATI driver.

Measures taken :

*Installed Fedora 10

*Did ssh login to the target system from my laptop to do the post installation setup.

* Installed the basic codecs, kernel packages and other necessary packages to make a kernel module from my local repo.

* Configured rpmfusion on the system.

* Did the following as root :

* yum –enablerepo=rpmfusion-nonfree-updates-testing install akmod-fglrx xoiorg-x11-drv-fglrx xorg-x11-drv-fglrx-libs.i386

* Xorg -configure :1

* aticonfig –initial -f

* Edit /etc/X11/xorg.conf :

* Add the following sections or edit accordingly :

Section “Extensions”
Option “Composite” “Enable”

Section “ServerFlags”
Option “AIGLX” “on”

Section “DRI”
Mode 0666

Add the following lines to the Device Section

Option        “OpenGLOverlay” “off”
Option        “VideoOverlay” “on”

* mv /boot/initrd-`uname -r`.img /boot/initrd-`uname -r`.img.backup
mkinitrd -v /boot/initrd-`uname -r`.img  `uname -r`

* Edit the grub.conf file to add “nopat” and “nomodeset” as kernel arguments.

* Reboot the system. akmod will build the kmod-fglrx for the concerned kernel during this boot.

Results :

Target system was up and running. No more hangs and crashes in the GUI. Installed FEL Packages in the system. Running well.

Reference :