Emiliano Ariel Lesende Inhalt |
Zusammenfassung:
Dies ist der Start einer Artikelserie, die Einblicke in den Linux Kernel und dessen Geheimnisse
gibt.
Dies ist der erste Artikel einer Serie über die Geheimnisse des Linux Kernels. Vielleicht hat der ein oder andere schon mal früher einen Blick auf den Quelltext des Kernels geworfen. In diesem Falle er man bemerkt haben, daß aus den paar ehemals 100 KB (komprimiert) großen Dateien, 300 Dateien mit mehr als 2 Millionen Zeilen Quelltext geworden sind, die im gepackten Zustand 9 MB Speicher belegen.
Diese Reihe wendet sich weniger an den Linux Neuling, als an den erfahrenen Programmierer. Natürlich steht es jedem frei, die Artikel zu lesen und der Autor wird sein Bestes geben, alle Fragen oder Unklarheiten, die per E-Mail auftreten, zu lösen.
Fast täglich werden neue Fehler entdeckt und neue Patches veröffentlicht. Heutzutage ist es fast unmöglich, den Quelltext als Ganzes zu verstehen. Er wird von vielen verschiedenen Programmierer unterhalten, welche sich zwar bemühen, einen einheitlichen Programmierstil beizubehalten, sich aber in ihrer Art untereinander unterscheiden.
Linux ist ein frei veröffentlichtes Betriebssystem für den PC und andere Plattformen. Es ist ist konform zum POSIX 1003.1 Standard und weist viele Eigenschaften von Unix System V und BSD 4.3 auf. Viele wichtige Teile des Linux Kernels, die in dieser Serie beschrieben werden, wurden von Linus Torvalds, einem finnischen Informatikstudenten, geschrieben. Der erste Kernel kam im November 1991 heraus.
Linux unterstützt richtiges Multitasking. Alle Prozesse laufen unabhängig voneinander, keiner wird gezwungen, den Prozessor für einen anderen Prozeß freizugeben, während er an der Reihe ist.
Linux ist nicht nur ein Multiuser Betriebssystem, es kann auch gleichzeitig von mehreren Benutzern genutzt werden. Linux kann die (gleichen) Systemresourcen unter den Benutzern teilen, die über verschiedene Terminals mit dem Rechner verbunden sind.
Es werden nur die für die Auführung notwendigen Teile eines Programmes in den Speicher geladen.
Ist der Systemspeicher völlig aufgebraucht, so sucht Linux sich 4KB Speicherseiten heraus, die momentan aus dem Speicher entfernt werden können, und speichert diese auf Festplatte. Diese werden dann bei Bedarf wieder von Platte in den ursprünglichen Speicherbereich geschrieben. Im Gegensatz zum Paging verwenden ältere Unix Systeme und einige gegenwärtige Betriebssysteme wie Microsoft Windows ein anderes Verfahren, bei welchem alle Speicherseiten eines Taskes auf Platte geschrieben werden, falls der Speicher knapp wird. Dies ist (offensichtlich) weniger effizient, als das Paging.
MS-DOS Benutzer sind es gewohnt, mit SmartDrive zu arbeiten, ein Programm, welches bestimmte feste Speicherbereiche benutzt, um Daten der Festplatte zwischenzuspeichern. Linux dagegen hat ein viel dynamischeres Caching System: Der Cache Speicher wird vergrößert, falls weniger Hauptspeicher genutzt wird oder halt verkleinert, wenn Benutzerprogramme mehr Speicher brauchen.
Bibliotheken (Libraries) stellen eine Sammlung von Routinen dar, welche von Programmen für die Verarbeitung von Daten genutzt werden können. Es gibt eine Anzahl von Standard-Bibliotheken, die gleichzeitg von mehr als einem Prozeß benutzt werden. Diese wurden bei alten Betriebssystemen in jedes Programm eingebunden und so mehrfach im Speicher gehalten, wenn weitere Programme gestartet wurden, die ebenfalls diese Bibliotheken nutzten. Dies war ein unnötiger Verbrauch von Speicherplatz. Bei modernen Betriebssystemen, wie Linux, wird geteilter (shared) Code nur einmal im Speicher gehalten und von allen Programmen, die darauf zugreifen wollen, geteilt.
POSIX 1003.1 definiert eine Standardschnittstelle für Unix Betriebssysteme. Diese wird durch eine Gruppen von C Funktionen realisiert und wird momentan von allen modernen Betriebssystemen unnterstützt. Microsoft Windows NT tut dies auch. Linux 1.2 ist 100% konform zu POSIX. Zusätzlich werden einige Schnittstellen von System V oder BSD unterstützt oder für bessere Kompatibilität implementiert.
Wer möchte nicht gerne jede DOS, Windows95, FreeBSD oder OS/2 Anwendung unter Linux nutzen ? Deswegen werden DOS, Windows oder Windows95 Emulatoren entwickelt. Desweiteren können unter Linux, Programme von anderen intel-basierten Unix Plattformen, die konform zu iBCS2 (intel Binary Compatibility) sind, ausgeführt werden.
Linux kann mit einer großen Zahl Dateisystemen unterschiedlichen Formates umgehen. Das zur Zeit meist genutzte ist das "Second Extended File System" (Ext2). Ein weiteres unterstütztes Format ist zum Beispiel auch "File Allocation Table" (FAT), welches von DOS basierten Systemen verwendet wird. Der Einsatz von FAT in einer Multiuser Umgebung ist aber unter dem Aspekt der Sicherheit bedenklich, wegen seiner konzeptionell bedingten Beschränktheit.
Linux kann in jedes lokale Netzwerk intergriert werden. Jeder Unix Service ist verfügbar, zum Beispiel "Networked File System" (NFS), entferntes Einloggen (telnet, rlogin), Einwahl mittels SLIP oder PPP, uvm. Es kann als Server oder Client für andere Netzwerke eingesetzt werden, inklusive Datei Sharing und Drucken für Macintosh, Netware und Windows.
Linux nutzt diese Technik für die Verwaltung von Nachrichten zwischen Prozessen, Semaphoren und Speicher Sharing.
Bevor nun das Augenmerk auf den Kernel gerichtet wird, sollte man sich erst einmal den Quelltext des Kernels anschauen
Verzeichnisstruktur des Quelltextes: Der Quelltext des Linux Kernels ist normalerweise unter /usr/src/linux zu finden, alle weiteren Verzeichnisse sind deshalb relativ von diesem aus zu sehen. Als Folge der Portierung auf nicht-Intel Architekturen, wurde der Verzeichnisbaum nach Version 1.0 geändert. Architekturspezifischer Code ist unter arch/ zu finden. Die Dateien für die Intel 386, 486, Pentium und Prntium Pro Prozessoren liegen unter arch/i386. Das Verzeichnis arch/mips ist für MIPS-basierte System da, arch/sparc für SPARC-basierte Plattformen, usw. Im folgenden wird vorallem die Intel Architektur betrachtet, da Linux momentan auf ihr am weitesten verbreitet ist.
Prinzipiell ist der Linux Kernel ein ganz normales C Programm. Er unterscheidet sich nur in zwei wichtigen Punkten. Während ein normales C Programm mit der main(int argc,char **argv) Routine startet, ist das beim Kernel start_kernel(void). Die Progammumgebung existiert zum Zeitpunkt des Systemstartes und während der Kernel geladen wird, noch nicht. Deswegen muß noch einiges getan werden, bevor die erste C Routine aufgerufen wird. Der Assembler Code, welcher diese Aufgaben übernimmt, liegt unter arch/i386/asm/.
Die entsprechende Assemblerroutine lädt den Kernel in den Speicher, und zwar an die absolute Adresse 0x100000 (1 Megabyte). Danach werden die Interrupt behandelnden Routinen, globale Datei Deskriptortabellen und Interrupt Deskriptortabellen installiert, die ausschließlich während der Initialisierung benutzt werden. Zu diesem Zeitpunkt wird der Prozessor in den Protected Mode geschaltet. Das Verzeichnis init/ enthält alle Routinen für die Initialisierung des Kernels. Hier ist auch die start_kernel() Routine, zuständig für die korrekte Initialisierung des Kernels, unter Betrachtung aller übergebenen Parameter. Der erste Prozeß wird ohne Zugriff von Systemaufrufen gestartet (das System selbst ist noch nicht geladen). Dies ist der berühmte Idle Prozeß, der die CPU Zeit "verbraucht", wenn diese von keinem anderen Prozeß benötigt wird.
Die Verzeichnisse kernel/ und arch/i386/kernel/ enthalten, wie ihr Name schon vermuten läßt, die Hauptteile des Kernels. Hier befinden sich die wichtigsten Systemaufrufe. Außerdem werden hier andere Aufgaben realisiert, wie die Zeitverwaltung, die Prozeßtabelle, die DMA und Interrupt Verwaltung und die Signalsteuerung.
Der Programmcode, welcher die Speicherverwaltung realisiert, ist in mm/ und arch/i386/mm/ zu finden. Diese Bereiche sind für die Speicherzuweisung und Freigabe an Prozesse, sowie für das Memory Paging zuständig.
Das "Virtual File System" (vfs) ist unter fs/ zu finden. Die verschiedenen Dateisysteme sind dort in den jeweiligen Verzeichnissen untergebracht. Die wichtigsten Dateisysteme sind Ext2 und Proc. Dieser werden später eingehender betrachtet.
Alle Betriebssysteme benötigen Treiber für einige Hardwarekomponenten. Diese sind im Linuxquelltext unter drivers/ zu finden.
Das Verzeichnis ipc/ enthält die Linuximplementation des System V IPCs.
Der Quelltext für einige Netzwerkprotokolle, Sockets und Internetdomains ist unter net/ abgelegt.
Einige C Standardroutinen sind in lib/ zu finden. Durch sie kann der Kernel selbst auf in C programmierte Elemente zugreifen.
Ladbare Module, die während der Übersetzung des Kernels erzeugt worden sind, werden in modules/ gespeichert, aber bis zur ersten Kompilierung des Kernels ist dieses Verzeichnis leer.
Das für die Entwickler wohl wichtigste Verzeichnis ist include/. Hier sind alle C Headerdateien zu finden, die speziell für den Kernel benutzt werden. Die für Intel Plattformen spezifischen Headerdateien sind in include/asm-386/ gespeichert.
Compiling: Ein neuer Kernel wird prinzipiell in 3 Schritten erzeugt:
In den nächsten Artikeln werden die Hintergründe dieser Skripte beleuchtet werden und wie sie modifiziert werden können, damit neue Optionen für die Konfiguration bereitstehen.
Ich hoffe, daß der Leser den Artikel nützlich fand. Kommentare, Vorschläge und Kritik kann jeder an elesende@nextwork.net senden.
This website is maintained by Miguel Angel Sepulveda © 1998 Emiliano Ariel Lesende LinuxFocus 1998 |