2013-08-07 7 views
5

Ich habe ein einfaches Kernel-Objekt, das ich für die Untersuchung im Kernel-Speicher erstellt.Linux Kernel Module (* .ko) Kompatibilität zwischen den Kernel

Wenn ich es auf meinem 64-Bit-Ubuntu (3.2) -Maschine bauen, funktioniert es gut auf diesem Rechner. Aber es wird nicht auf meinem 64-Bit-Ubuntu (3.9) -Maschine insmod. Und umgekehrt. Es gibt mir ein "-1 ungültiges Modulformat" -Fehler, wenn ich versuche, es auf einer anderen Kernrev auszuführen als der, auf dem ich es gebaut hatte.

Ich dachte, Insmod verknüpft es dynamisch gegen die exportierte Symboltabelle und die exportierte Symboltabelle ändert sich nicht zwischen Kernel-Revisionen. (Es wird angehängt.)

Kann mir jemand sagen, wie ich ein Kernelmodul (.ko) bauen kann, das mit zukünftigen (oder vergangenen) Linux-Kernel kompatibel ist, ohne auf diesem Kernel neu erstellt werden zu müssen?

Hier ist mein Make-Datei:

ccflags-y = -g

obj-m + = access_mem.o

alle: make -C/lib/modules/$ (shell uname -r)/build M = $ (PWD) Module

sauber: make -C/lib/modules/$ (shell uname -r)/build M = $ (PWD) sauber

+0

Ihr Ubuntu 3.2 ist eine 32-Bit oder 64-Bit Version? Die gleiche Frage mit Ihrem Ubuntu 3.9 – nouney

+0

Beide 64-Bit. Danke für die Erinnerung an diesen wichtigen Datenpunkt. –

Antwort

5

Joe, Ubuntu (3.2) vielleicht mit Kernel-Version x.y.z, aber Ubuntu (3.9) vielleicht mit Kernel-Version x.y.z1. Wenn sich die Kernel-Versionen unterscheiden, müssen Sie Ihren Treiber für diese bestimmte Kernel-Version erstellen/kompilieren. Wenn die Kernel-Versionen identisch sind, muss der Treiber nicht erstellt werden. Wichtig ist, dass jedes Treibermodul mit dem version.ko-Modul kompiliert oder gebaut wurde (welches die Informationen über die Kernelversion enthält, auf die das Treibermodul gebaut wurde), während beim Laden des Kernelmoduls diese Informationen und die Kernelversion geprüft werden, falls sie unterschiedlich sind dann wirft "-1 ungültiges Modulformat" oder, wenn passed, dann wird Kernelmodul erfolgreich geladen. Um ein Kernel-Modul zu entwickeln, das zukunfts- oder rückwärtskompatibel ist, müssen Sie wissen, welche Kernel-Version welche API- oder Funktionssignatur geändert hat: ioctl-Signatur geändert von Kernel-Version 2.3.36, daher sollte Ihr Code wie folgt lauten:

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) 
static long minor_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 
#else 
static int minor_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 
                   unsigned long arg) 
#endif 

Wenn das Kernelmodul so entwickelt wurde, ist es zukunfts- oder rückwärtskompatibel. Kompatibilität ist nur die Anpassung von APIs oder Funktionssignaturen etc .. Änderungen für die Kernel-Version durch Beibehaltung der älteren APIs oder Funktionssignatur etc .. in Ihrem Kernel-Modul wie im obigen Beispiel, aber Sie müssen noch bauen/kompilieren Sie Ihr Kernel-Modul gegen die Kernel-Version, auf die Sie versuchen, zu laden.

+0

Als ich "(3.2)" und "(3.9)" schrieb, meinte ich "mit Kernel Version 3.2" und "mit Kernel Version 3.9", also ja thx. –

+0

In diesem Fall ist "insmod" wirklich nur für Entwickler. Es war nie dazu gedacht, vorgefertigte binäre Module zu verwenden, die von Firma A direkt an das vorhandene Linux-Image von Endbenutzer B verteilt wurden. Einverstanden? –

+0

Joe, insmod ist nur ein Dienstprogramm, um vordefinierte Binärdatei einzufügen. Ich denke, Insmod ist intelligent genug, um die Versionsabhängigkeit zu überprüfen. Wenn Übereinstimmungen geladen werden oder ein Fehler ausgegeben wird. http://tuxthink.blogspot.in/2010/09/insmod-explained.html –

1

ich bin kein e Xpert über das Thema, aber ich bin mir ziemlich sicher, dass Sie Ihren Treiber gegen jede Version des Kernels erstellen müssen. Da die Symbole zwischen den Kernel-Versionen gleich bleiben, bin ich ziemlich sicher, dass dies nach dem Lesen von https://www.kernel.org/doc/Documentation/stable_api_nonsense.txt nicht der Fall ist.

+0

In diesem Fall ist "insmod" wirklich nur für Entwickler. Es war nie dazu gedacht, vorgefertigte binäre Module zu verwenden, die von Firma A direkt an das vorhandene Linux-Image von Endbenutzer B verteilt wurden. Einverstanden? –

+0

Ich bin mir ziemlich sicher, dass Sie Lademodule in den Kernel zwingen können, dh: Module, die für 3.9.10 gebaut wurden, können zwangsweise in 3.10.4 geladen werden. – dklt

+0

Das Laden der Kraft ist nicht sicher; Es kann Ihr System zum Absturz bringen oder schlimmer. – Michael