J'ai lu pas mal de choses sur la façon de compiler un module de noyau sur (et pour) le Raspberry Pi, mais je ne suis toujours pas tout à fait capable de comprendre pourquoi cela ne fonctionne pas. J'ai pu construire le module, mais il rend compte Invalid module format
lorsque j'essaie de trouver insmod
le résultat. Voici le processus que j'ai suivi. Tout d'abord, en tant que root sous /root
j'ai exécuté le script shell suivant:
getKernel.sh
#! /usr/bin/bash
FIRMWARE_HASH=$(zgrep "* firmware as of" /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | head -1 | awk '{ print $5 }')
KERNEL_HASH=$(wget https://raw.githubusercontent.com/raspberrypi/firmware/$FIRMWARE_HASH/extra/git_hash -O -)
git clone https://github.com/raspberrypi/linux
cd linux
git checkout $KERNEL_HASH
wget https://raw.githubusercontent.com/raspberrypi/firmware/$FIRMWARE_HASH/extra/Module.symvers
zcat /proc/config.gz >.config
make oldconfig
make modules_prepare
ln -s /root/linux /lib/modules/$(uname -r)/build
Les premières lignes proviennent de http://lostindetails.com/blog/post/Compiling-a-kernel-module-for-the-raspberry-pi-2
Le reste, j'ai écrit pour automatiser davantage le processus. Une fois que tout cela fonctionne correctement, j'ai la source qui doit correspondre exactement au noyau en cours d'exécution, la configuration à faire correspondre et un lien symbolique. Il y a eu quelques redirections depuis l'emplacement Web de github (apparemment c'est maintenant https://raw.githubusercontent.com/ ) mais aucune erreur réelle.
Ensuite, je deviens l' pi
utilisateur par défaut et dans un répertoire nommé /home/pi/projects/lkm
j'ai ce code source pour un module jouet très simple:
Bonjour c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Do-nothing test driver");
MODULE_VERSION("0.1");
static int __init hello_init(void){
printk(KERN_INFO "Hello, world.\n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_INFO "Goodbye, world.\n");
}
module_init(hello_init);
module_exit(hello_exit);
Enfin, je construis le module avec ce Makefile
Makefile
MODSRC=/home/pi/projects/lkm
obj-m+=hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=${MODSRC} modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=${MODSRC} clean
Enfin, j'essaie de charger le module:
sudo insmod hello.ko
Le résultat est cependant décevant:
insmod: ERREUR: impossible d'insérer le module hello.ko: format de module non valide
Détails éventuellement pertinents
J'utilise actuellement la dernière jessie
version de Raspbian sur un Raspberry Pi2.
$ uname --kernel-release --kernel-version
4.1.13-v7+ #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.9/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.9.2 (Raspbian 4.9.2-10)
Malheureusement, je ne sais pas comment résoudre ce problème ou le corriger. Des indices?
Réponses:
Tout d'abord, assurez-vous d'utiliser les en-têtes de noyau appropriés. Je suppose que vos en-têtes de noyau et votre code source sont plus mis à jour que le noyau que vous utilisez.
Essayez de faire
apt-get update && apt-get upgrade
puis réinstallez le module. Si le problème persiste, vérifiez que vos en-têtes de noyau correspondent à votre noyau actuel, recompilez à nouveau puis essayez d'installer.Remarque: j'utilise Jessie.
MISE À JOUR: exécutez-les en tant que root.
Vous devrez peut-être redémarrer. Après cela, continuez avec les commandes ci-dessous, toujours en utilisant le compte root.
Si
rpi-source
jette une erreur GCC (quelque chose à propos d'une incompatibilité de version), ce n'est pas grave tant que votre version GCC actuelle est supérieure . Exécuterrpi-source --skip-gcc
au lieu derpi-source
Ensuite, passez à votre exemple Hello World. Créez le dossier et
cd
dedans. Créez ensuite les fichiers.Des dossiers:
Bonjour c
Makefile (sensible à la casse?)
Maintenant que vous avez vos fichiers, vous pouvez continuer et exécuter les commandes de construction Hello World habituelles:
Vous devriez maintenant vérifier
dmesg
. La dernière ligne doit s'imprimer enHello World :)
surbrillance rouge.Si vous le faites, félicitations. Vous venez de créer et d'installer un module noyau.
Maintenant, supprimez-le en utilisant
rmmod hello
.dmesg
devrait maintenant imprimerGoodbye World!
surligné en rouge.Sources: 1 2 3
la source
rpi-source
pièce soit suffisante. Vous pouvez essayer de construire le vôtre à partir de ce point.Il existe une version beaucoup plus simple ici, testé sur jessie et extensible .
sudo apt-get install raspberrypi-kernel-headers
puis lorsque vos fichiers sont en place:
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
Exemple
Créez le
hello
répertoire, allez à l'intérieur et créez les fichiers suivants:hello.c
etMakefile
.Je recommande de travailler en tant qu'utilisateur normal, et non root , seulement
insmod
,rmmod
et lesmake modules_install
commandes nécessitent des autorisations root, et le nécessairesudo
est indiqué dans les commandes suivantes.bonjour.c (inchangé, votre fichier)
Makefile (modifié)
Usage
make
(dans le même répertoire que le Makefile)sudo insmod hello.ko
Hello World :)
dans la sortie dedmesg
sudo rmmod hello
Goodbye, world.
la sortie dedmesg
sudo make modules_install
installera le module à sa place, ainsimodprobe
fonctionnera.la source
rpi-update
, arpi-update
été suggéré dans la réponse deapt
référentiel de Raspbian , si je ne me trompe pas. Mettre à jour le noyau signifiait exécuter lerpi-update
script d'Hexxeh . De nos jours, la mise à jourraspberrypi-kernel
ou l'exécutionrpi-update
font à peu près la même chose.raspberrypi-kernel-headers
, il installe généralement des en-têtes de noyau incompatibles, par expérience (les en-têtes ont tendance à être une version plus récente que le noyau), d'où la raison pour laquelle j'ai choisi de "passer au manuel".dans le
getKernel.sh
fichier ajouteravant
(maintenant dans l'image rpi par défaut /proc/config.gz n'existe pas)
la source