Pick a Free OS

Writing a Linux device driver

What do I need to know about writing drivers?

Basic knowledge of kernel compilation, a good deal of programming

experience in C under Linux and lastly, the right techniques of data

structures, like linked list is essential along with their data types.

The first thing a programmer must know before attempting to write a

driver, is to know how the Linux kernel source compiles, paying attention

to the compilation process (the gcc compiler flags).

Choosing the device type

a) Block drivers

A block device is something that can host a filesystem such as a disk. A

block device can only be accessed as multiples of a block, where a block

is usually one kilobyte of data .

b) Character drivers

A character device is one that can be accessed like a file, and a char

driver is in charge of implementing this behaviour. This driver implements

the open, close, read and write system calls. The console and parallel

ports are examples of char devices.

Device drivers in Linux are known as modules and can be loaded dynamically

into the kernel using the insmod command.

A single module can be compiled alone, and also can be linked to the

kernel (here, care has to be taken on the type of driver).

eg: A simple module

#define MODULE

#include <linux/module.h>

int init_module (void) /* Loads a module in the kernel */


printk("Hello kernel \n");

return 0;


void cleanup_module(void) /* Removes module from kernel */


printk("GoodBye Kernel\n");


Compiling the module

# gcc -c hello.c

# insmod hello.o

The output is

Hello kernel

# rmmod hello.o

GoodBye Kernel

How init_module works?

init_module loads the relocated module image into kernel space and runs

the module's init function.

The module image begins with a module structure and is followed by code

and data as appropriate.

The module structure is defined as follows:

struct module


unsigned long size_of_struct;

struct module *next;

const char *name;

unsigned long size;

long usecount;

unsigned long flags;

unsigned int nsyms;

unsigned int ndeps;