Ich habe einiges darüber gelesen, wie man ein Kernelmodul auf (und für) den Raspberry Pi kompiliert, aber ich bin immer noch nicht in der Lage herauszufinden, warum es nicht funktioniert. Ich konnte das Modul erstellen, aber es meldet sich, Invalid module format
wenn ich insmod
das Ergebnis versuche . Hier ist der Prozess, dem ich gefolgt bin. Zuerst habe /root
ich als root unter das folgende Shell-Skript ausgeführt:
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
Die ersten Zeilen stammen von http://lostindetails.com/blog/post/Compiling-a-kernel-module-for-the-raspberry-pi-2
Den Rest habe ich geschrieben, um mehr von dem Prozess zu automatisieren. Sobald das alles erfolgreich läuft, habe ich die Quelle, die genau zum laufenden Kernel passen sollte, die passende Konfiguration und einen Symlink. Es gab einige Weiterleitungen von der Github-Website (anscheinend ist es jetzt https://raw.githubusercontent.com/ ), aber keine tatsächlichen Fehler.
Dann werde ich zum Standardbenutzer pi
und habe in einem Verzeichnis mit dem Namen /home/pi/projects/lkm
folgenden Quellcode für ein sehr einfaches Spielzeugmodul:
Hallo 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);
Zum Schluss baue ich das Modul mit diesem 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
Zum Schluss versuche ich das Modul zu laden:
sudo insmod hello.ko
Das Ergebnis ist jedoch enttäuschend:
insmod: ERROR: Modul konnte nicht eingefügt werden hello.ko: Ungültiges Modulformat
Möglicherweise relevante Details
Ich verwende die aktuellste jessie
Version von Raspbian auf einem 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)
Leider bin ich mir nicht sicher, wie ich das Problem weiter beheben oder beheben soll. Irgendwelche Hinweise?
Antworten:
Stellen Sie zunächst sicher, dass Sie die richtigen Kernel-Header verwenden. Ich gehe davon aus, dass Ihre Kernel-Header und der Quellcode aktueller sind als der Kernel, den Sie ausführen.
Versuchen Sie,
apt-get update && apt-get upgrade
das Modul erneut zu installieren. Wenn das Problem weiterhin besteht, überprüfen Sie dreimal, ob Ihre Kernel-Header mit Ihrem aktuellen Kernel übereinstimmen, kompilieren Sie erneut und versuchen Sie dann, ihn zu installieren.Hinweis: Ich benutze Jessie.
UPDATE: Führen Sie diese als root aus.
Möglicherweise müssen Sie neu starten. Fahren Sie danach mit den folgenden Befehlen fort und verwenden Sie weiterhin das Root-Konto.
Wenn
rpi-source
ein GCC-Fehler auftritt (etwas über eine Versionsinkongruenz), ist dies in Ordnung , solange Ihre aktuelle GCC-Version höher ist . Laufenrpi-source --skip-gcc
stattrpi-source
Fahren Sie dann mit Ihrem Hello World-Beispiel fort. Erstellen Sie den Ordner und
cd
hinein. Erstellen Sie dann die Dateien.Dateien:
Hallo c
Makefile (Groß- und Kleinschreibung beachten ?)
Jetzt, da Sie Ihre Dateien haben, können Sie die üblichen Hello World-Build-Befehle ausführen:
Sie sollten jetzt überprüfen
dmesg
. Die letzte Zeile sollteHello World :)
rot hervorgehoben werden.Dann herzlichen Glückwunsch. Sie haben gerade ein Kernelmodul erstellt und installiert.
Entfernen Sie es nun mit
rmmod hello
.dmesg
sollte jetztGoodbye World!
rot hervorgehoben drucken .Quellen: 1 2 3
quelle
rpi-source
Teil ausreicht. Sie können versuchen, Ihre von diesem Punkt aus aufzubauen.Hier gibt es eine viel einfachere Version, die auf Jessie und Stretch getestet wurde .
sudo apt-get install raspberrypi-kernel-headers
und dann, wenn Ihre Dateien vorhanden sind:
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
Beispiel
Erstellen Sie das
hello
Verzeichnis, gehen Sie hinein und erstellen Sie die folgenden Dateien:hello.c
undMakefile
.Ich empfehle als Ihre normalen Benutzer, nicht als root , nur
insmod
,rmmod
undmake modules_install
Befehle erfordern root - Rechte, und die erforderlichensudo
ist in den folgenden Befehlen angezeigt.hallo.c (unverändert, deine Datei)
Makefile (geändert)
Verwendung
make
(im selben Verzeichnis wie das Makefile)sudo insmod hello.ko
Hello World :)
in der Ausgabe vondmesg
sudo rmmod hello
Goodbye, world.
int die Ausgabe vondmesg
sudo make modules_install
installiert das Modul dort, wo es hingehört,modprobe
und funktioniert auch.quelle
rpi-update
,rpi-update
wurde in der Antwort vonapt
Repository integriert, wenn ich mich nicht irre. Das Aktualisieren des Kernels bedeutete, Hexxehsrpi-update
Skript auszuführen . Heutzutage machen Aktualisierungenraspberrypi-kernel
oder das Ausführenrpi-update
so ziemlich dasselbe.raspberrypi-kernel-headers
, installiert es in der Regel nicht übereinstimmen Kernel - Header, aus Erfahrung (die Header sind in der Regel eine neuere Version als der Kernel sein), warum also entschied ich mich auf „manuell gehen“.in
getKernel.sh
Datei hinzufügenVor
(jetzt im Standard rpi image /proc/config.gz nicht vorhanden)
quelle