mardi 18 septembre 2007

Comment écrire un module pour linux ?

Après avoir fait des essais autour d'un driver windows, j'étais quelque peu échaudé par ce genre d'activité.

C'est pourquoi, je me suis contenté de faire un petit driver expérimental sous linux. Rien de
fabuleux, juste pour m'habituer à la démarche. Pour linux, un driver peut se présenter sous le forme
d'un module, ou directement être compilé dans le noyau.

Préparation
Pour commencer il faut bien avoir installer le compilateur gcc et make. Ensuite il faut s'assurer que les headers du kernel soient présents. (j'ai fait mes premiers pas sur un noyau 2.6.18)
Ensuite à partir de là, il s'agit de créer des liens symboliques sur les entêtes du noyau, de la manière suivante :

ln -s /lib/modules/2.6.18-5-686/build/ /usr/src/linux
ln -s /usr/src/linux-headers-2.6.18-5-686 /lib/modules/2.6.18-5-686/build/

Maintenant, la compilation du module devrait marcher...

Mon premier module à un but unique : s'inscrire dans la liste des modules chargés.

Le code source (helloworld1.c)


#include linux/init.h
#include linux/module.h
#include linux/kernel.h

/* Les sources contiennent une série de macros permettant de faire */
/* des déclarations diverses au sujets des modules, comme ici la */
/* licence.*/
MODULE_LICENSE("GPL");

static int hello_init(void) {
printk("<1>Bonjour monde\n");
return 0;
}

static void hello_exit(void) {
printk("<1>Au revoir\n");
}

module_init(hello_init);
module_exit(hello_exit);

Le seule chose que ce driver fait, c'est d'écrire un message en log système lorsqu'on
charge et lorsque on le décharge. Il est un peu prématuré de parler de driver pour ce
petit module car il n'est pas capable de faire grand chose. Il ne possède pas de
numéro majeur/mineur non plus.

La compilation

  • Le Makefile

obj-m := helloworld1.o

  • Un petit script pour lancer la compilation

make -C /usr/src/linux-headers-2.6.18-5-686 M=`pwd` modules


Bien entendu, ce script est à adapter en fonction de la version du noyau.

L'installation

par la commande insmod ./helloworld.ko

ensuite pour vérifier : lsmod

Module Size Used by
helloworld1 1408 0
ppdev 8676 0
lp 11012 0
button 6672 0
.....

puis on le désinstalle : rmmod helloworld1.ko

lsmod

Module Size Used by
ppdev 8676 0
lp 11012 0
button 6672 0
ac 5188 0
......

dans le log système on trouve :

Sep 18 20:56:58 localhost kernel: Bonjour monde
Sep 18 20:58:11 localhost kernel: Au revoir

En fait, tout cela est très simple, en tout cas plus simple que sur un système windows.