|
I-RT04 REALZEITSYSTEME WS04
|
Wie in der vorausgehenden Vorlesung deutlich gemacht wurde, soll das Realzeitbetriebssystem RTAI in Kombination mit dem Betriebssystem Linux benutzt werden. Da in diesem Zusammenhang der Modulbegriff wichtig wird --die RTAI-Funktionalitäten werden als Module nachgeladen--, soll hier Linux soweit erklärt werden, wie es zum Verständnis dieses Zusammenhanges notwendig ist. Es sei wieder verwiesen auf die Webseite von Herrn Houssaini, ganz besonders aber auf die Webseite des hervorragenden Buches von Alessandro RUBINI/Jonathan CORBET [2nd Edition June 2001], hier besonders Kap.2 (dieses Buch ist komplett online verfügbar, dazu die Beispiele im Quellkode!).
Module sind Teile des Betriebsystems, die sich im laufenden Betrieb einfügen und entfernen lassen.
Es sind Programme, die im Kern laufen. Linuxmodule werden mit der Programmiersprache C entwickelt und sind im einfachsten Fall folgendermaßen aufgebaut (Beispiel von der Webseite zu Rubini):
/* * $Id: hello.c,v 1.7 2000/08/17 11:11:48 rubini Exp $ */ #define MODULE #include <linux/module.h> int init_module(void) { printk("<1>Hello, world\n"); return 0; } void cleanup_module(void) { printk("<1>Goodbye cruel world\n"); }
Ein Linux bzw. RTAI-Linux Modul hat im Gegensatz zu einem herkömmlichen C-Programm keine main()-Funktion. Es bestehet aus mindestens diesen zwei Funktionen: int init_module(void) und void cleanup_module(void).
Für die Ausgabe kann die bekannte C-Funktion printf von einem Modul nicht benutzt werde, dafür bietet der Kern die Funktion printk (RTAI: rt_printk).
Die Präprozessoranweisung #define MODULE sorgt dafür, dass der für die Modul- und Kernelprogrammierung notwendige Anteil in den Headerdateien Verwendung findet.
Besteht das Programm(Modul) aus mehreren Dateien, wird zunächst jede Datei für sich kompiliert (Option ld -r) und es wird eine einzige Objektdatei Moduol.o erzeugt. Dann werden alle Module miteinander verbunden. Damit entsteht eine einzige ausführbare Datei.
Dies sei hier an einem Beispiel mit einem Kernel der Version 2.4.xx durchgespielt (mit Version 2.6.xx funktioniert es nicht, da das Modulformat anders ist!).
Will man das Modul kompilieren, ohne den Kernel konfiguriert zu haben, ergibt sich folgende Fehler-Meldung:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # gcc -I /usr/src/linux -I/usr/src/linux/include -O2 -Wall -D__KERNEL__ -DCONFIG_M386 -c hello.c In file included from /usr/src/linux/include/linux/module.h:10, from hello.c:5: /usr/src/linux/include/linux/config.h:4:28: linux/autoconf.h: Datei oder Verzeichnis nicht gefunden In file included from /usr/src/linux/include/linux/list.h:241, from /usr/src/linux/include/linux/module.h:12, from hello.c:5: /usr/src/linux/include/linux/prefetch.h:13:26: asm/prefetch.h: Datei oder Verzeichnis nicht gefunden In file included from /usr/src/linux/include/linux/module.h:299, from hello.c:5: /usr/src/linux/include/linux/version.h:6:2: #error "The kernel sources in /usr/src/linux are not yet configured." /usr/src/linux/include/linux/version.h:7:2: #error "Please run 'make cloneconfig && make dep' in /usr/src/linux/" /usr/src/linux/include/linux/version.h:8:2: #error "to get a kernel that is configured like the running kernel." /usr/src/linux/include/linux/version.h:9:2: #error "Alternatively, you can copy one of the config files" /usr/src/linux/include/linux/version.h:10:2: #error "arch/$ARCH/defconfig.* to .config, and run" /usr/src/linux/include/linux/version.h:11:2: #error "'make oldconfig && make dep' to configure the kernel" /usr/src/linux/include/linux/version.h:12:2: #error "for that configuration." In file included from hello.c:5: /usr/src/linux/include/linux/module.h:301: error: parse error before "UTS_RELEASE"
Nach Bereitstellung der Sourcen und Ausführung des folgenden Befehls:
make cloneconfig && make dep
ist der Kernel konfiguriert und in der Datei /usr/src/linux/include/linux/version.h finden sich dann folgende Daten:
#define UTS_RELEASE "2.4.21-99-default" #define LINUX_VERSION_CODE 132117 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
Wiederholt man jetzt den Befehl zum Kompilieren gibt es keine Fehlermeldung mehr:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # gcc -I /usr/src/linux -I/usr/src/linux/include -O2 -Wall -D__KERNEL__ -DCONFIG_M386 -c hello.c
Der folgende Aufruf des Moduls produziert zwar Warnungen, aber das Modul wird geladen und ausgeführt:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # insmod ./hello.o Warning: loading ./hello.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information about tainted modules Module hello loaded, with warnings
Da das Modul von einem xterm-Fenster aufgerufen wird, erscheint die Ausgabe nicht direkt auf dem Bildschirm, sondern wird der Datei /usr/var/messages angefügt:
Dec 4 19:16:01 turing kernel: Hello, world
Wird das Modul wieder entfernt:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # rmmod hello
Dann erscheint die Meldung bei der Entfernung des Moduls wieder in /usr/var/messages:
Dec 4 19:41:20 turing kernel: Goodbye cruel world
Für weitere Details siehe das Kapitel 2 (Webversion) (Kapitel 2 (lokale Version) des hervorragenden Buches von Alessandro RUBINI/Jonathan CORBET [2nd Edition June 2001]
Beispiel der /proc/ioports-Datei auf dem laptop des Autors während der Bearbeitung dieser Vorlesung:
0000-001f : dma1 0020-003f : pic1 0040-005f : timer 0060-006f : keyboard 0070-007f : rtc 0080-008f : dma page reg 00a0-00bf : pic2 00c0-00df : dma2 00f0-00ff : fpu 0170-0177 : ide1 01f0-01f7 : ide0 0376-0376 : ide1 0378-037a : parport0 03c0-03df : vesafb 03f6-03f6 : ide0 03f8-03ff : serial(auto) 0cf8-0cff : PCI conf1 1000-103f : Intel Corp. 82371AB/EB/MB PIIX4 ACPI 1040-105f : Intel Corp. 82371AB/EB/MB PIIX4 ACPI 1060-107f : Intel Corp. 82371AB/EB/MB PIIX4 USB 1060-107f : usb-uhci 1080-108f : Intel Corp. 82371AB/EB/MB PIIX4 IDE 1080-1087 : ide0 1088-108f : ide1 1400-14ff : ESS Technology ES1978 Maestro 2E 1400-14ff : ESS Maestro 2000-2fff : PCI Bus #01 2000-20ff : ATI Technologies Inc Rage Mobility P/M AGP 2x 4000-40ff : PCI CardBus #02 4400-44ff : PCI CardBus #02 4800-48ff : PCI CardBus #06 4800-48ff : PCI device 13d1:ab08 4800-48ff : tulip 4c00-4cff : PCI CardBus #06
Beispiel der /proc/iomem-Datei auf dem laptop des Autors während der Bearbeitung dieser Vorlesung:
00000000-0009f7ff : System RAM 0009f800-0009ffff : reserved 000a0000-000bffff : Video RAM area 000c0000-000c7fff : Video ROM 000f0000-000fffff : System ROM 00100000-0ffeffff : System RAM 00100000-0028dadf : Kernel code 0028dae0-00324f63 : Kernel data 0fff0000-0ffffbff : ACPI Tables 0ffffc00-0fffffff : ACPI Non-volatile Storage 10000000-10000fff : Texas Instruments PCI1225 10001000-10001fff : Texas Instruments PCI1225 (#2) 10400000-107fffff : PCI CardBus #02 10800000-10bfffff : PCI CardBus #02 10c00000-10ffffff : PCI CardBus #06 10c00000-10c1ffff : PCI device 13d1:ab08 11000000-113fffff : PCI CardBus #06 11000000-110003ff : PCI device 13d1:ab08 11000000-110003ff : tulip e0000000-e3ffffff : Intel Corp. 440BX/ZX/DX - 82443BX/ZX/DX Host bridge fc000000-fdffffff : PCI Bus #01 fc000000-fc000fff : ATI Technologies Inc Rage Mobility P/M AGP 2x fd000000-fdffffff : ATI Technologies Inc Rage Mobility P/M AGP 2x fd000000-fd7effff : vesafb fff80000-ffffffff : reserved
Welche Funktionen haben Modukle unter Linux?
Wie ist ein Modul unter Linux aufgebaut?
Welches sind die zwei wichtigsten Funktionsaufrufe unter Linux?