ubuntuusers.de

Keine neuen Beiträge Kernel Modul Programmierung - Fehler beim Kompilieren! Brauche mal Hilfe!

Status: Ungelöst | Ubuntu-Version: Ubuntu 9.04 (Jaunty Jackalope)
Antworten |

Combichrist

Anmeldungsdatum:
29. November 2006

Beiträge: Zähle...

Guten Tag,

ich habe von meinem Professor ein Stükchen Programmcode bekommen, da ich mich in ein Thema einarbeiten soll und dabei Module in den Kernel laden soll.

Ich nutze Ubuntu 9.04 mit Kernel 2.6.28-15-generic

Es handelt sich um folgenden Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <linux/module.h>
#include <linux/kernel.h>


int init_module ( void )
{
    printk ( "<7>" "Hello Kernel !\n" );
    return 0;
}

void cleanup_module ( void )
{
    printk ( "<7>" "Goodbye Kernel !\n" );
} 

welchen ich mittels:

1
gcc -D__KERNEL__ -DMODULE -Wall -O6 -I/usr/src/linux-headers-2.6.28-15/include -c ex01.c -o ex01.o

kompilieren möchte!

Dabei bekomme ich folgende Fehlermeldungen und Abhängigkeitsprobleme:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
In Datei, eingefügt von /usr/src/linux-headers-2.6.28-15/include/linux/list.h:6,
von /usr/src/linux-headers-2.6.28-15/include/linux/module.h:9,
von ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/prefetch.h:14:27: Fehler: asm/processor.h: No such file or directory
/usr/src/linux-headers-2.6.28-15/include/linux/prefetch.h:15:23: Fehler: asm/cache.h: No such file or directory
In file included from /usr/src/linux-headers-2.6.28-15/include/linux/list.h:6,
from /usr/src/linux-headers-2.6.28-15/include/linux/module.h:9,
from ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/prefetch.h:53: Fehler: expected declaration specifiers or »...« before »size_t«
In Datei, eingefügt von /usr/src/linux-headers-2.6.28-15/include/linux/module.h:9,
von ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/list.h:7:24: Fehler: asm/system.h: No such file or directory
In Datei, eingefügt von /usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:11,
von /usr/src/linux-headers-2.6.28-15/include/linux/cache.h:4,
von /usr/src/linux-headers-2.6.28-15/include/linux/time.h:7,
von /usr/src/linux-headers-2.6.28-15/include/linux/stat.h:60,
von /usr/src/linux-headers-2.6.28-15/include/linux/module.h:10,
von ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/linkage.h:5:25: Fehler: asm/linkage.h: No such file or directory
In Datei, eingefügt von /usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:15,
von /usr/src/linux-headers-2.6.28-15/include/linux/cache.h:4,
von /usr/src/linux-headers-2.6.28-15/include/linux/time.h:7,
von /usr/src/linux-headers-2.6.28-15/include/linux/stat.h:60,
von /usr/src/linux-headers-2.6.28-15/include/linux/module.h:10,
von ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h:17:24: Fehler: asm/bitops.h: No such file or directory
In file included from /usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:15,
from /usr/src/linux-headers-2.6.28-15/include/linux/cache.h:4,
from /usr/src/linux-headers-2.6.28-15/include/linux/time.h:7,
from /usr/src/linux-headers-2.6.28-15/include/linux/stat.h:60,
from /usr/src/linux-headers-2.6.28-15/include/linux/module.h:10,
from ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h: In Funktion »get_bitmask_order«:
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h:29: Warnung: Implizite Deklaration der Funktion »fls«
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h: In Funktion »hweight_long«:
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h:45: Warnung: Implizite Deklaration der Funktion »hweight32«
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h:45: Warnung: Implizite Deklaration der Funktion »hweight64«
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h: In Funktion »fls_long«:
/usr/src/linux-headers-2.6.28-15/include/linux/bitops.h:112: Warnung: Implizite Deklaration der Funktion »fls64«
In file included from /usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:16,
from /usr/src/linux-headers-2.6.28-15/include/linux/cache.h:4,
from /usr/src/linux-headers-2.6.28-15/include/linux/time.h:7,
from /usr/src/linux-headers-2.6.28-15/include/linux/stat.h:60,
from /usr/src/linux-headers-2.6.28-15/include/linux/module.h:10,
from ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/log2.h: Auf höchster Ebene:
/usr/src/linux-headers-2.6.28-15/include/linux/log2.h:52: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »is_power_of_2«
In Datei, eingefügt von /usr/src/linux-headers-2.6.28-15/include/linux/cache.h:4,
von /usr/src/linux-headers-2.6.28-15/include/linux/time.h:7,
von /usr/src/linux-headers-2.6.28-15/include/linux/stat.h:60,
von /usr/src/linux-headers-2.6.28-15/include/linux/module.h:10,
von ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:21:21: Fehler: asm/bug.h: No such file or directory
In file included from /usr/src/linux-headers-2.6.28-15/include/linux/cache.h:4,
from /usr/src/linux-headers-2.6.28-15/include/linux/time.h:7,
from /usr/src/linux-headers-2.6.28-15/include/linux/stat.h:60,
from /usr/src/linux-headers-2.6.28-15/include/linux/module.h:10,
from ex01.c:1:
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:167: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:168: Fehler: Format-Zeichenkettenargument ist kein Zeichenkettentyp
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:167: Warnung: In Konflikt stehende Typen für eingebaute Funktion »snprintf«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:169: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:169: Warnung: In Konflikt stehende Typen für eingebaute Funktion »vsnprintf«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:171: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:172: Fehler: Format-Zeichenkettenargument ist kein Zeichenkettentyp
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:173: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:236: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »printk_timed_ratelimit«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:301: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:303: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:303: Fehler: expected declaration specifiers or »...« before »bool«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:306: Fehler: expected declaration specifiers or »...« before »size_t«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:306: Fehler: expected declaration specifiers or »...« before »bool«
/usr/src/linux-headers-2.6.28-15/include/linux/kernel.h:308: Fehler: expected declaration specifiers or »...« before »size_t« 

usw! Nun meine Frage, erkennt jmd. auf den ersten Blick was das Problem ist und wie ich es in den Griff bekomme?

Wäre echt nett! Danke schon mal!

Mike

epyx

Avatar von epyx

Anmeldungsdatum:
22. März 2007

Beiträge: 48

Du übersetzt das Ganze nicht richtig.

Erstelle dir ein Makefile, das nimmt dir die Arbeit ab.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
obj-m := ex01.o

KDIR  := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	rm -f *.*o
	rm -f *.mod*
	rm -f Module*
	rm -f module*

install:
	modprobe -r ex01
	depmod -a

Combichrist

(Themenstarter)

Anmeldungsdatum:
29. November 2006

Beiträge: 56

Super, das hat schon mal geklappt!

Nun erscheint folgende Fehlermeldung wenn ich das Module laden möchte:

1
2
root@mike-vmware:~/Desktop/Module/example_01# insmod ex01.o
insmod: error inserting 'ex01.o': -1 Invalid module format

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Combichrist schrieb:

Super, das hat schon mal geklappt!

Nun erscheint folgende Fehlermeldung wenn ich das Module laden möchte:

1
2
root@mike-vmware:~/Desktop/Module/example_01# insmod ex01.o
insmod: error inserting 'ex01.o': -1 Invalid module format

Mitlerweile nutzt der Kernel Module in einem anderen Format, diese haben die Endung ".ko". Mehr kann ich dir dazu auch nicht sagen, den rest musst du selber heraus finden.

Combichrist

(Themenstarter)

Anmeldungsdatum:
29. November 2006

Beiträge: 56

Okay, folgender Befehl:

1
root@mike-vmware:~/Desktop/Module/example_01# insmod ex01.ko

ergibt folgende Ausgabe in der /var/log/messages

1
Aug 24 18:03:19 mike-vmware kernel: [ 5059.067227] ex01: module license 'unspecified' taints 

Scheint auf jeden Fall schon mal geklappt zu haben ☺. Nun forsche ich mal weiter! Danke für die Starthilfe!

Combichrist

(Themenstarter)

Anmeldungsdatum:
29. November 2006

Beiträge: 56

Nochmal eine Frage zum Befehl:

1
root@mike-vmware:~/Desktop/Module/example_01# insmod ex01.ko

Müsste ich nicht beim Aufruf von insmod ex01.ko eine Ausgabe auf dem Terminal erhalten?

Erhalte nämlich keine Ausgabe der Funktion:

1
2
3
4
5
int init_module ( void )
{
    printk ( "<7>" "Hello Kernel !\n" );
    return 0;
}

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Nicht daß ich mich damit auskennte, aber in die Kernellogs würde ich mal greppen, ob da kein Hello steht.

epyx

Avatar von epyx

Anmeldungsdatum:
22. März 2007

Beiträge: 48

Das Modul lässt sich nicht laden, da nur modinfo ex01.ko funktionieren kann.

Siehe hier. Dafür ist dein Kernelmodul einfach noch nicht "fertig" genug.

Im Übrigen müssen Kernelmodule immer lizenziert sein um Lizenzansprüche im Vorfeld zu klären.

Füg einfach das hier ein :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * ex01.c − Demonstrates module documentation.
 */
#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */
#include <linux/init.h>         /* Needed for the macros */
#define DRIVER_AUTHOR "Name des Autors"
#define DRIVER_DESC   "kurze Beschreibung"

/*
 * You can use strings, like this:
 */
/*
 * Get rid of taint message by declaring code as GPL.
 */
MODULE_LICENSE("GPL");
/*
 * Or with defines, like this:
 */
MODULE_AUTHOR(DRIVER_AUTHOR);    /* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC);         /* What does this module do */
/*
 * This module uses /dev/testdevice. The MODULE_SUPPORTED_DEVICE macro might
 * be used in the future to help automatic configuration of modules, but is
 * currently unused other than for documentation purposes.
 */
MODULE_SUPPORTED_DEVICE("testdevice");

Dann ergibt auch ein Blick ins log :

1
Aug 24 21:26:59 spielomat kernel: Hello world 1

Combichrist

(Themenstarter)

Anmeldungsdatum:
29. November 2006

Beiträge: 56

Danke für eure vielen Hilfen und Ratschläge. So langsam blicke ich etwas durch. Ich habe den Kernel-Log selbst schon gefunden und ausgegeben, für den Anfang ist das erstmal okay.

Kann ich denn vorhandene, globale (Kernel-)Variablen wie z.B. "dev_base" vom Typ net_device* irgendwie nun benutzen, oder zumindest irgendwie drauf zugreifen? Hab ein "extern struct net_device *dev_base" eingefügt aber anscheinend macht er nicht das was es soll.

dev_base ist übrigens ein Zeiger, zu einer verketteten Liste von net_devices. Und genau auf diese möchte ich wenn irgendwie möglich zugreifen. Noch jmd. einen Tipp?

epyx

Avatar von epyx

Anmeldungsdatum:
22. März 2007

Beiträge: 48

Wieso was meckert er denn ?

Habe das Folgende hinzugefügt und es funktioniert ohne Probleme.

1
2
3
#include <linux/netdevice.h>

extern struct net_device               *dev_base;

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

@Combichrist: "Macht nicht was er soll" ist keine hilfreiche Fehlerbeschreibung. Zeige den Quellcode und dazu passende Fehlermeldung. Im Allgemeinen sind Kernel-globale Symbole in einer bestimmten Header-Datei definiert, die Du entsprechend einbinden kannst. Dann kannst Du dieses Symbol auch verwenden. Allerdings musst Du zum Zugriff auf bestimmte Symbole MODULE_LICENSE("GPL") angeben, da der Kernel manche Symbole nur für GPL-Module exportiert.

@epyx: Nichts von alledem ist zwingend erforderlich, um ein Kernelmodul laden zu können. Ein Modul kompiliert und lädt problemlos auch ohne MODULE_LICENSE, MODULE_AUTHOR, usw.

Module, die nicht GPL lizenziert sind, "beschmutzen" ("taint") den Kernel nur. Das schlägt sich in Log-Dateien und entsprechenden Flags in Tracebacks nach Panics wieder, Kernel-Entwickler verweigern bei einem tainted kernel in der Regel jeglichen Support. Außerdem werden manche Debugging-Features (z.B. Lock-Debugging) automatisch deaktiviert, wenn das tainted-Flag im Kernel gesetzt wird. Außerdem können Nicht-GPL-Module nicht alle Kernelsymbole verwenden. KMS ist beispielsweise GPL-Modulen vorbehalten.

epyx

Avatar von epyx

Anmeldungsdatum:
22. März 2007

Beiträge: 48

Gut wieder was gelernt. Hatte nur noch grob in Erinnerung, dass man das Lizenzmodell mit angeben sollte.

Hello_World

Anmeldungsdatum:
13. Juni 2006

Beiträge: 3620

Muss man nicht normalerweise mit dem module_init-Makro angeben, welche Funktion das Modul initialisieren soll?

Combichrist

(Themenstarter)

Anmeldungsdatum:
29. November 2006

Beiträge: 56

@ Lunar

Du hast recht, es handelt sich um folgenden Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>


extern struct net_device *dev_base;
extern struct list_head dev_base_head;


int init_module ( void )
{
	printk ( "<7>" "Hello Kernel !\n" );
	return 0;
}

void test (void)
{
printk("%s", dev_base->name);
}

void cleanup_module ( void )
{
	printk ( "<7>" "Goodbye Kernel !\n" );
}

dev_base ist wie schon oben erwähnt ein Struct "net_device". Dieses ist hier: http://www.oreilly.de/german/freebooks/linuxdrive2ger/x19513.html genauer beschrieben.

Um zu testen ob ich wirklich Zugriff darauf habe wollte ich mit:

printk("%s", dev_base->name);

auf den ersten Eintrag der Liste zugreifen. Im Grunde genommen müsste ich hier auf das net_device Struct von eth0 zugreifen da ich keine anderen Interfaces konfiguriert habe. Dementsprechend müsste ich auch als Inhalt der name-Variable "eth0" ausgegeben bekommen wenn ich das Modul lade.

Aber erstens erscheint folgende Warning beim Kompilieren:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
root@mike-vmware:~/Desktop/Module/example_01/test# make
make -C /lib/modules/2.6.28-15-generic/build M=/home/mike/Desktop/Module/example_01/test modules
make[1]: Betrete Verzeichnis '/usr/src/linux-headers-2.6.28-15-generic'
  CC [M]  /home/mike/Desktop/Module/example_01/test/ex01.o
  Building modules, stage 2.
  MODPOST 1 modules
'''WARNING: "dev_base" [/home/mike/Desktop/Module/example_01/test/ex01.ko] undefined!'''
  CC      /home/mike/Desktop/Module/example_01/test/ex01.mod.o
  LD [M]  /home/mike/Desktop/Module/example_01/test/ex01.ko
make[1]: Verlasse Verzeichnis '/usr/src/linux-headers-2.6.28-15-generic'

und zweitens erscheint folgender Fehler beim Laden des Moduls:

1
2
root@mike-vmware:~/Desktop/Module/example_01/test# insmod ex01.ko
insmod: error inserting 'ex01.ko': -1 Unknown symbol in module

Ich bin wirklich absoluter Anfänger was Kernelprogrammierung usw. geht. Ich versuche gerade irgendwie einen Überblick zu gewinnen. Ziel soll es am Ende erstmal sein auf ein bestehendes net_device Struct zuzugreifen und über dessen Funktionen Daten über die Netzwerkkarte zu schicken.

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

@Combichrist: Dieses Buch beschreibt die Kernelversion 2.4. Für die Kernelversion 2.6 ist dieses Buch schlicht und einfach unbrauchbar. Daher dürfte auch ein Großteil der Verwirrung resultieren, denn im Kernel 2.6 hat sich an der Modul-Entwicklung einiges geändert.

Im Kernel 2.6 musst du die Makros module_init und module_exit verwenden, um die Eintritts- und Austritts-Funktionen des Moduls zu deklarieren. Außerdem solltest Du Kernel-globale Symbole nicht direkt deklarieren, sondern den entsprechenden Header dafür einbinden. Die Prioritäten für printk() solltest Du nicht als Zeichenkette, sondern mit den entsprechenden Makros wie KERN_ALERT angeben.

Das eigentliche Problem ist wohl, dass es dev_base im aktuellen Kernel gar nicht mehr gibt (jedenfalls habe ich beim Blick in die Kernelquellen kein derartiges Symbol entdecken können). Deswegen findet es der Linker beim Laden nicht, was zum beobachteten Fehler führt.

Antworten |