Il semble que le chargeur de modules sous Linux soit devenu très susceptible. Vous possédez un driver qui fonctionne sur un noyau Ubuntu estampillé 2.6.32-22 ? Lors de la mise à jour suivante vers un noyau 2.6.32-24, insmod le refuse !

Un début d'explication

Tout d'abord, il faut savoir que le message d'erreur laconique de insmod, « Invalid module format », est complété par un message plus explicite dans /var/log/messages. Cela peut aider.

Ensuite, chaque module possède une chaîne vermagic. En gros, pour pouvoir charger un module, il doit avoir le même vermagic que ceux fournis avec le noyau. On affiche ce vermagic avec modinfo, par exemple modinfo -F vermagic truc.ko.

Le chapitre idoine de The Linux Kernel Module Programming Guide donne quelques informations.

L'idée pour avoir le bon vermagic est d'utiliser pour compiler le module exactement la même configuration de noyau que pour le noyau lui-même. On commence donc par récupérer le fichier de configuration du noyau de la distribution :

cp /boot/config-`uname -r` .config

uname -r permet d'obtenir la chaîne de version exacte du noyau en cours de fonctionnement. Le suffixe -xy ajouté à cette chaîne de version s'appelle EXTRAVERSION. Il faut donc logiquement changer cette valeur dans le Makefile du noyau.

Il faut ensuite recompiler le module, mais pour que cela fonctionne correctement, il faut commencer par recompiler le noyau. Or un make isolé recompilera tous les modules, ce qui n'est pas pratique quand on s'intéresse uniquement à un module. On peut utiliser alors un make vmlinux que l'on peut interrompre rapidement (après la ligne marquée SPLIT).

On essaie alors de recompiler uniquement le module qui nous intéresse en indiquant son chemin dans la variable SUBDIRS, par exemple :

SUBDIRS=drivers/media/radio/si470x make modules

En théorie, il me semble que cette procédure devrait fonctionner. Or, dans mon expérience, cela se solde toujours par un message « disagrees about version of symbol module_layout »...

La méthode qui fonctionne

Je ne sais pas précisément pourquoi la méthode précédente ne fonctionne pas. Je soupçonne qu'il y ait des informations de version en plus du vermagic. Je suis preneur de toute information à ce sujet. Ce que je comprends, c'est qu'avoir le bon vermagic ne suffit pas ; il faut en plus compiler le module avec précisément les mêmes fichiers de symboles que ceux qui ont servi lors de la compilation du noyau.

Or ces fichiers sont fournis en général dans /lib/modules/.../build/. La solution qui fonctionne est donc encore plus simple que ce qui précède : il faut se déplacer dans le répertoire des sources du noyau, puis lancer une commande du type

make -C /lib/modules/`uname -r`/build \
   SUBDIRS=`pwd`/drivers/media/radio/si470x modules