| Zeile 6: | Zeile 6: | ||
==Vor dem Start== | ==Vor dem Start== | ||
| − | Frisch ans Werk, Editor und Compiler ausgepackt | + | Frisch ans Werk, Editor und Compiler ausgepackt – aber halt! Bevor es wirklich losgeht, solltest Du Dir einige Fragen beantworten, damit Du weißt, was Du überhaupt entwickeln willst und worüber Du Informationen suchen musst. |
===Willst Du wirklich ein OS schreiben?=== | ===Willst Du wirklich ein OS schreiben?=== | ||
Die Frage klingt vielleicht seltsam, aber sie ist genau so gemeint, wie sie da steht. Willst Du wirklich ein OS entwickeln? Ist Dir klar, was ein [[Betriebssystem]] macht? | Die Frage klingt vielleicht seltsam, aber sie ist genau so gemeint, wie sie da steht. Willst Du wirklich ein OS entwickeln? Ist Dir klar, was ein [[Betriebssystem]] macht? | ||
| − | Wenn Du in erster Linie an eine grafische Oberfläche denkst, bist Du hier womöglich falsch. Grafische Oberflächen sind ein interessantes Thema | + | Wenn Du in erster Linie an eine grafische Oberfläche denkst, bist Du hier womöglich falsch. Grafische Oberflächen sind ein interessantes Thema – aber eine vollkommen andere Baustelle. Ein OS ist die Schnittstelle zur Hardware. Das heißt, Du wirst eine Speicherverwaltung bauen, einen Scheduler, Treiber für störrische Hardware. Du wirst alles tun, nur keine bunten Pixel auf den Bildschirm bringen – oder falls doch, wird dir direkt anschließend die saubere Basis fehlen, damit man mit diesen Pixeln auch etwas sinnvolles anfangen kann. |
Wer sich nicht mit Hardware herumschlagen möchte, kann sich ein DOS oder ein abgespecktes Linux als Grundlage nehmen und seine Oberfläche darauf aufbauen. | Wer sich nicht mit Hardware herumschlagen möchte, kann sich ein DOS oder ein abgespecktes Linux als Grundlage nehmen und seine Oberfläche darauf aufbauen. | ||
| + | |||
| + | ===Voraussetzungen=== | ||
| + | Obwohl dieses Wiki den Einstieg in Betriebssystementwicklung so einfach wie möglich machen will, ist Betriebssystementwicklung dennoch sehr komplex, und einige Fertigkeiten sind einfach nötig. Ich will nicht sagen, dass man die Fertigkeiten nicht durch "learning-by-doing" erwerben kann, jedoch wird das bei diesem Thema sehr frustrierend. Außerdem wärst Du dann allein, weil die meisten Supporter bei Erklärungen zu Betriebssystemtheorie nicht bei Adam und Eva anfangen können. | ||
| + | |||
| + | ====Unverzichtbar==== | ||
| + | * Programmiererfahrung. Wenn Du noch nie ein Programm geschrieben hast, bist Du hier ziemlich sicher falsch. Wenn Du einen Einstieg suchst, dann werden Dir die Lowlevel-Forenmitglieder sicher trotzdem dabei helfen, Tutorials und Ressourcen zum Anfang zu finden. | ||
| + | * Gute Kenntnis des Systems. Wenn Du regelmäßig mit der Bedienung Deines Betriebssystems kämpfst, dann ist es schwer, dabei Arbeit getan zu kriegen. Ein Windowsnutzer braucht eventuell sogar mehr Erfahrung als ein Linuxer, da sich manche Tools auf Windows zu Beginn recht zickig verhalten können. | ||
| + | * Neugier und Geduld. Vermutlich die heimlichen Kernqualifikationen jedes Programmierers. Ohne Neugier und Geduld wird es schwer, die Frustrationen der Betriebssystementwicklung zu überstehen. | ||
| + | |||
| + | ====Hilfreich, aber nicht unbedingt nötig==== | ||
| + | * Unix-Kenntnisse. | ||
| + | * Assembler. Zwar braucht man nur einige Zeilen Assembler (wenn man es richtig macht), und das nötige Stück Assembler sich haben viele durch "learning-by-doing" angeeignet, jedoch helfen Kenntnisse von Assembler enorm beim Verständnis. Es lohnt sich eigentlich bei jedem Projekt, eine Abstraktionsschicht tiefer schauen zu können. | ||
| + | * Englisch. Handbücher und andere Dokumentation sind kaum auf Deutsch zu finden, und das, was man findet, ist häufig veraltet. Außerdem ist OSDev.org oft noch besser als das Lowlevel-Wiki. Wir arbeiten dran ''*g*'' | ||
===Die Programmiersprache=== | ===Die Programmiersprache=== | ||
| − | Ein weit verbreitetes Vorurteil ist, dass man ein Betriebssystem komplett in [[Assembler]] schreiben muss. Quatsch. Man kann, wenn man es möchte, aber man muss nicht. Wahr ist, dass man um einige wenige Zeilen Assembler nicht herumkommen wird | + | Ein weit verbreitetes Vorurteil ist, dass man ein Betriebssystem komplett in [[Assembler]] schreiben muss, oder sogar erst einen Compiler entwickeln müsste. Quatsch. Man kann, wenn man es möchte, aber man muss nicht. Wahr ist, dass man um einige wenige Zeilen Assembler nicht herumkommen wird, aber es hält sich in Grenzen. |
Ein übliches Vorgehen ist es, nur das nötigste in Assembler zu schreiben und für den Rest eine Hochsprache zu benutzen. Für die Wahl dieser Hochsprache gibt es im großen und ganzen zwei Alternativen: | Ein übliches Vorgehen ist es, nur das nötigste in Assembler zu schreiben und für den Rest eine Hochsprache zu benutzen. Für die Wahl dieser Hochsprache gibt es im großen und ganzen zwei Alternativen: | ||
* Du nimmst [[C]]. Fast jeder spricht diese Sprache und Du bekommst Unmengen an Beispielcode in [[C]]. Dein Betriebssystem ist eins von vielen und im Forum oder im IRC wird dir fast jeder helfen können. | * Du nimmst [[C]]. Fast jeder spricht diese Sprache und Du bekommst Unmengen an Beispielcode in [[C]]. Dein Betriebssystem ist eins von vielen und im Forum oder im IRC wird dir fast jeder helfen können. | ||
| − | * Du nimmst nicht [[C]]. Du wirst Dich vor allem am Anfang wesentlich seltener beim Kopieren von Code erwischen, weil es einfach nicht geht, ohne ihn in deine Sprache zu übersetzen. Ja, das ist durchaus positiv. Auf der anderen Seite bist du ein Außenseiter und erhältst vielleicht nicht ganz so umfangreich Hilfe und musst Dich möglicherweise öfter selbst durchschlagen | + | * Du nimmst nicht [[C]]. Du wirst Dich vor allem am Anfang wesentlich seltener beim Kopieren von Code erwischen, weil es einfach nicht geht, ohne ihn in deine Sprache zu übersetzen. Ja, das ist durchaus positiv. Auf der anderen Seite bist du ein Außenseiter und erhältst vielleicht nicht ganz so umfangreich Hilfe und musst Dich möglicherweise öfter selbst durchschlagen – gerade wenn es um Besonderheiten deiner Sprache oder Deines Compilers geht. |
Von Mitgliedern der Lowlevel-Community benutzte Alternativen zu [[C]] sind beispielsweise [[C++]] oder [[Pascal]] (mit FreePascal oder mit Tricks auch Delphi als Compiler). Theoretisch würde auch [[FreeBASIC]] funktionieren. Andere Sprachen hat hier meines Wissens noch niemand versucht, könnten natürlich aber trotzdem funktionieren. | Von Mitgliedern der Lowlevel-Community benutzte Alternativen zu [[C]] sind beispielsweise [[C++]] oder [[Pascal]] (mit FreePascal oder mit Tricks auch Delphi als Compiler). Theoretisch würde auch [[FreeBASIC]] funktionieren. Andere Sprachen hat hier meines Wissens noch niemand versucht, könnten natürlich aber trotzdem funktionieren. | ||
===Entwicklungsumgebung und Tools=== | ===Entwicklungsumgebung und Tools=== | ||
| − | Um Dein eigenes Betriebssystem zu entwickeln, brauchst Du ein paar Werkzeuge. Auf die wichtigsten davon gehe ich in diesem Abschnitt kurz ein. Wie man sich eine | + | Um Dein eigenes Betriebssystem zu entwickeln, brauchst Du ein paar Werkzeuge. Auf die wichtigsten davon gehe ich in diesem Abschnitt kurz ein. Wie man sich eine Entwicklungsumgebung einrichtet, welche Tools man für sein Vorhaben benötigt und auf welchen Plattformen (Linux, Windows, ...) dies möglich ist, wird im Artikel [[Entwicklungsumgebung]] genauer erläutert. |
==== Dein Computer ==== | ==== Dein Computer ==== | ||
| − | Fangen wir vorne an: Du brauchst einen PC. Ja, Du hast recht, Du brauchst natürlich strenggenommen keinen PC. Aber es wäre geschickt, denn ich nehme an, Du willst ein x86-Betriebssystem schreiben. Wenn Du wider Erwarten für eine andere Plattform entwickeln möchtest, teil Dich im Forum mit, das wird auch andere interessieren | + | Fangen wir vorne an: Du brauchst einen PC. Ja, Du hast recht, Du brauchst natürlich strenggenommen keinen PC. Aber es wäre geschickt, denn ich nehme an, Du willst ein x86-Betriebssystem schreiben. Wenn Du wider Erwarten für eine andere Plattform entwickeln möchtest, teil Dich im Forum mit, das wird auch andere interessieren – allerdings bist dann Du derjenige, der erklären darf. Aber zurück zum PC: Am besten hat dieser ein Diskettenlaufwerk, denn Disketten sind für den Anfang das handlichste. Und ein 386er oder höher sollte es schon sein – aber das sollte heutzutage machbar sein. |
==== Dein Betriebssystem ==== | ==== Dein Betriebssystem ==== | ||
| − | Eine Stufe weiter kommen wir zum Betriebssystem. Da Dein eigenes Betriebssystem noch nicht fertig ist, wirst Du vorerst mit einem bestehenden vorlieb nehmen müssen. Hast Du ein [[Linux]] installiert? Wunderbar, nimm das. Oder eine BSD-Variante. Trotzdem möchte ich hier nicht lügen, deshalb: Ja, man kann auch [[Windows]] nehmen. Aber dazu braucht es schon eine gewisse masochistische Veranlagung (jedenfalls wenn man GRUB und daher ELF benutzen möchte | + | Eine Stufe weiter kommen wir zum Betriebssystem. Da Dein eigenes Betriebssystem noch nicht fertig ist, wirst Du vorerst mit einem bestehenden vorlieb nehmen müssen. Hast Du ein [[Linux]] installiert? Wunderbar, nimm das. Oder eine BSD-Variante. Trotzdem möchte ich hier nicht lügen, deshalb: Ja, man kann auch [[Windows]] nehmen. Aber dazu braucht es schon eine gewisse masochistische Veranlagung (jedenfalls wenn man GRUB und daher ELF benutzen möchte – und das ist der von uns dringend empfohlene Weg). Unter Windows wirst Du aller Voraussicht nach eine Weile mit der Umgebung basteln müssen, während es unter Linux einfach läuft. Man könnte jetzt versuchen, einen Kausalzusammenhang herzustellen, warum die Windowsbenutzer häufiger bei Assembler steckenbleiben – aber lassen wir das... |
Falls Du kein Linux auf deinem Rechner installieren willst und auch keinen Bock hast, unter Windows eine geignete Umgebung herstellen, nimm einfach Knoppix. Das ist allerdings auf Dauer keine richtige Lösung. Deswegen empfehle ich Dir, Linux richtig zu installieren. Alternativ kannst Du das Linux-System auch auf einer virtuellen Maschine wie [[VMware|VMware Server]], [[VirtualBox]] oder [[Microsoft Virtual PC]] Installieren. | Falls Du kein Linux auf deinem Rechner installieren willst und auch keinen Bock hast, unter Windows eine geignete Umgebung herstellen, nimm einfach Knoppix. Das ist allerdings auf Dauer keine richtige Lösung. Deswegen empfehle ich Dir, Linux richtig zu installieren. Alternativ kannst Du das Linux-System auch auf einer virtuellen Maschine wie [[VMware|VMware Server]], [[VirtualBox]] oder [[Microsoft Virtual PC]] Installieren. | ||
==== Deine Tools ==== | ==== Deine Tools ==== | ||
| − | Dann brauchst Du Editor und Compiler. Als Editor hast Du sicher schon Deinen eigenen Favoriten (nämlich vim), aber wenn nicht, dann findest Du | + | Dann brauchst Du Editor und Compiler. Als Editor hast Du sicher schon Deinen eigenen Favoriten (nämlich vim), aber wenn nicht, dann findest Du sicherlich im Artikel zu [[Editor]]en einen passenden. |
| − | |||
| − | |||
Auch beim Compiler ist die Sache relativ klar: Wenn Du [[C]] nimmst, wird der Compiler im Allgemeinen gcc sein und unter [[Linux]] ist damit alles geklärt. Wenn Du gcc unter [[Windows]] benutzt, solltest du dir überlegen, ob Du nicht einen Crosscompiler benutzt, der ELF-Dateien erzeugt. Bahnhof? Macht nichts, vertrau mir, installier ihn Dir einfach. | Auch beim Compiler ist die Sache relativ klar: Wenn Du [[C]] nimmst, wird der Compiler im Allgemeinen gcc sein und unter [[Linux]] ist damit alles geklärt. Wenn Du gcc unter [[Windows]] benutzt, solltest du dir überlegen, ob Du nicht einen Crosscompiler benutzt, der ELF-Dateien erzeugt. Bahnhof? Macht nichts, vertrau mir, installier ihn Dir einfach. | ||
| Zeile 44: | Zeile 55: | ||
==== Dein Emulator ==== | ==== Dein Emulator ==== | ||
| − | Schließlich brauchst Du auch noch eine Möglichkeit, dein Werk zu testen. Ja, ich weiß, der PC. Aber du willst nicht nach jeder kleinen Änderungen neu booten müssen, richtig? Besorg dir einen Emulator. VMware ist ganz nett, aber hilft Dir beim Debuggen nicht besonders weiter. Nimm [[Qemu]] oder [[Bochs]] | + | Schließlich brauchst Du auch noch eine Möglichkeit, dein Werk zu testen. Ja, ich weiß, der PC. Aber du willst nicht nach jeder kleinen Änderungen neu booten müssen, richtig? Besorg dir einen Emulator. VMware ist ganz nett, aber hilft Dir beim Debuggen nicht besonders weiter. Nimm [[Qemu]] oder [[Bochs]] – oder am besten beides. Wenn Dein System in beiden Emulatoren funktioniert, ist immer noch genug Zeit, es auf den echten PC loszulassen. |
* [http://www.qemu.org http://www.qemu.org] | * [http://www.qemu.org http://www.qemu.org] | ||
| Zeile 59: | Zeile 70: | ||
* [[GRUB-Image erstellen]] (Falls Du Windows benutzt, ist es vermutlich einfacher, ein vorhandenes GRUB-Image z.B. von [[týndur]] zu nehmen und den Kernel durch den eigenen zu ersetzen) | * [[GRUB-Image erstellen]] (Falls Du Windows benutzt, ist es vermutlich einfacher, ein vorhandenes GRUB-Image z.B. von [[týndur]] zu nehmen und den Kernel durch den eigenen zu ersetzen) | ||
| − | Wenn Du trotz diesen Vorteilen darauf bestehst, Deinen Bootloader selbst zu schreiben | + | Wenn Du trotz diesen Vorteilen darauf bestehst, Deinen Bootloader selbst zu schreiben – so sei es. In den ersten Ausgaben des [[:Kategorie:Magazin|Magazins]] findest Du die dazu nötigen Informationen. In den folgenden Abschnitten gehe ich allerdings davon aus, dass [[GRUB]] benutzt wird. Du solltest also sicherstellen, dass Du eine vergleichbare Umgebung herstellst – insbesondere, dass Du im [[Protected Mode]] bist. |
===Hello World und weiter=== | ===Hello World und weiter=== | ||
| Zeile 71: | Zeile 82: | ||
Wenn Du GRUB benutzt, bist Du zwar bereits am Anfang im Protected Mode, allerdings mit einem Standardsatz von Deskriptortabellen. Es wäre jetzt an der Zeit, das zu ändern. | Wenn Du GRUB benutzt, bist Du zwar bereits am Anfang im Protected Mode, allerdings mit einem Standardsatz von Deskriptortabellen. Es wäre jetzt an der Zeit, das zu ändern. | ||
| − | Oh, Du hast keine Ahnung, was Du Dir unter Deskriptortabellen vorzustellen hast? Lies Dir am besten den Artikel zum Protected Mode durch | + | Oh, Du hast keine Ahnung, was Du Dir unter Deskriptortabellen vorzustellen hast? Lies Dir am besten den Artikel zum Protected Mode durch – oder wenn Du einen groben Überblick hast, kannst Du auch direkt zum Artikel über die [[GDT]] übergehen. Wenn Du Deinen Bootloader selbst schreibst, findest Du dort auch Informationen, wie Du selbst in den Protected Mode umschaltest. Außerdem ist das Protected-Mode-Tutorial auf den Seiten der FH Zwickau zu empfehlen. |
* [[Protected Mode]] | * [[Protected Mode]] | ||
| Zeile 78: | Zeile 89: | ||
* [http://www.fh-zwickau.de/doc/prmo/start.htm Protected-Mode-Tutorial der FH Zwickau] | * [http://www.fh-zwickau.de/doc/prmo/start.htm Protected-Mode-Tutorial der FH Zwickau] | ||
| − | Was Du zunächst machen musst, ist, eine GDT im Speicher aufzubauen. Mit der Beschreibung auf den genannten Seiten sollte das kein Problem darstellen (aber gräme Dich nicht, wenn es nicht im ersten Versuch hinhaut | + | Was Du zunächst machen musst, ist, eine GDT im Speicher aufzubauen. Mit der Beschreibung auf den genannten Seiten sollte das kein Problem darstellen (aber gräme Dich nicht, wenn es nicht im ersten Versuch hinhaut – das ist für viele die erste Stelle, wo sie erst einmal eine Weile hängen). |
Wenn Du die GDT aufgebaut hast, kannst Du sie anschließend laden. Das ist einer der wenigen Fälle, wo Du tatsächlich Assembler brauchst. Wenn Du C benutzt, könnte dir der Artikel über [[Inline-Assembler mit GCC]] helfen. Ansonsten schlag in der Dokumentation deines Compilers nach, wie es dort funktioniert. | Wenn Du die GDT aufgebaut hast, kannst Du sie anschließend laden. Das ist einer der wenigen Fälle, wo Du tatsächlich Assembler brauchst. Wenn Du C benutzt, könnte dir der Artikel über [[Inline-Assembler mit GCC]] helfen. Ansonsten schlag in der Dokumentation deines Compilers nach, wie es dort funktioniert. | ||
| Zeile 95: | Zeile 106: | ||
* [[Programmable Interrupt Controller]] | * [[Programmable Interrupt Controller]] | ||
| − | Wenn Du auch Hardwareinterrupts am Laufen hast, hast Du die ersten großen Hürden genommen. Für diejenigen unter uns, die gerne etwas sehen und irgendwas zum Spielen brauchen, wäre das ein guter Zeitpunkt, einfach mal einen Tastaturtreiber zu schreiben und ein bisschen was auszuprobieren. Es kommen noch genug schwere Sachen, bis Dein Produkt sich zurecht ein Betriebssystem nennen kann, aber hey, wenn ich zwei Zahlen eingeben kann und die werden addiert | + | Wenn Du auch Hardwareinterrupts am Laufen hast, hast Du die ersten großen Hürden genommen. Für diejenigen unter uns, die gerne etwas sehen und irgendwas zum Spielen brauchen, wäre das ein guter Zeitpunkt, einfach mal einen Tastaturtreiber zu schreiben und ein bisschen was auszuprobieren. Es kommen noch genug schwere Sachen, bis Dein Produkt sich zurecht ein Betriebssystem nennen kann, aber hey, wenn ich zwei Zahlen eingeben kann und die werden addiert – das ist doch schonmal ein Erfolgserlebnis, oder? Mich hat das jedenfalls motiviert. |
==Der eigentliche Kernel== | ==Der eigentliche Kernel== | ||
| Zeile 103: | Zeile 114: | ||
Unter der ''Architektur'' Deines Betriebssystem ist die Art und Weise zu verstehen, wie die Komponenten Deines Systems zusammenspielen. Bevor Du anfängst, Code für die eigentliche Funktionalität des Kernels zu schreiben, solltest Du Dir klar sein, in welche Richtung die Reise gehen soll. | Unter der ''Architektur'' Deines Betriebssystem ist die Art und Weise zu verstehen, wie die Komponenten Deines Systems zusammenspielen. Bevor Du anfängst, Code für die eigentliche Funktionalität des Kernels zu schreiben, solltest Du Dir klar sein, in welche Richtung die Reise gehen soll. | ||
| − | * Die allerwichtigste Entscheidung, die das Aussehen Deines Betriebssystems am schwerwiegendsten beeinflussen wird, ist die Entscheidung zwischen [[Monolithischer Kernel|monolithischem Kernel]] (die Hardwaretreiber sind alle im Kernel) und [[Microkernel]] (der Kernel macht nur das notwendigste, Treiber sind eigenständige [[Userspace]]-Prozesse) | + | * Die allerwichtigste Entscheidung, die das Aussehen Deines Betriebssystems am schwerwiegendsten beeinflussen wird, ist die Entscheidung zwischen [[Monolithischer Kernel|monolithischem Kernel]] (die Hardwaretreiber sind alle im Kernel) und [[Microkernel]] (der Kernel macht nur das notwendigste, Treiber sind eigenständige [[Userspace]]-Prozesse) – oder natürlich beliebiger Mischformen davon, z.B. ein modularisierter Monolith wie [[Linux]]. |
* Besonders beim Microkernel ist eine zentrale Frage, wie die [[Interprozesskommunikation]] aussehen soll. Auch bei einem monolithischen Kernel ist es kein Fehler, sich diese Frage zu stellen, auch wenn sie eher nachrangig ist. | * Besonders beim Microkernel ist eine zentrale Frage, wie die [[Interprozesskommunikation]] aussehen soll. Auch bei einem monolithischen Kernel ist es kein Fehler, sich diese Frage zu stellen, auch wenn sie eher nachrangig ist. | ||
* Wie soll die Schnittstelle der Programme zum Kernel aussehen? (z.B. [[Syscall|Syscalls]]) | * Wie soll die Schnittstelle der Programme zum Kernel aussehen? (z.B. [[Syscall|Syscalls]]) | ||
===Die Aufgaben des Kernels=== | ===Die Aufgaben des Kernels=== | ||
| − | Bevor Du Dir anschaust, welche Funktionen Dein Kernel bieten soll, versichere Dich, dass Du weißt, was ein [[Kernel]] überhaupt ist. Ja, klar, er ist der Kern des Betriebssystems. Und weiter? Seine zentrale Aufgabe ist es, die Ressourcen des Systems zu verwalten | + | Bevor Du Dir anschaust, welche Funktionen Dein Kernel bieten soll, versichere Dich, dass Du weißt, was ein [[Kernel]] überhaupt ist. Ja, klar, er ist der Kern des Betriebssystems. Und weiter? Seine zentrale Aufgabe ist es, die Ressourcen des Systems zu verwalten – z.B. den laufenden Programmen Speicher zuzuteilen. |
Im Allgemeinen wird für Betriebssysteme im [[Protected Mode]] ein Modell verwendet, in dem der Kernel in [[Ring]] 0 (Kernel Mode) und alle Programme in Ring 3 (User Mode) laufen. Als grobe Richtung kannst Du Dir merken, dass der Kernel alles das ist, was in Ring 0 läuft. Wenn ein User-Mode-Programm Betriebssystemfunktionen benötigt (z.B. mehr Speicher), ruft es den Kernel auf. | Im Allgemeinen wird für Betriebssysteme im [[Protected Mode]] ein Modell verwendet, in dem der Kernel in [[Ring]] 0 (Kernel Mode) und alle Programme in Ring 3 (User Mode) laufen. Als grobe Richtung kannst Du Dir merken, dass der Kernel alles das ist, was in Ring 0 läuft. Wenn ein User-Mode-Programm Betriebssystemfunktionen benötigt (z.B. mehr Speicher), ruft es den Kernel auf. | ||