Eigenes OS?
-
Melde mich aus dem Urlaub zurück.
Schaut man sich die in Tanenbaum "Modern OS" konkret untersuchten OS an, so findet man Unix/Linux, MS Vista und Symbian OS. Die meisten Hobby-OS sind wohl Linux/Unix-Clones.
Ich wollte zunächst mit dem starten, was viele als Teenager - in diesem Alter versuchen einige begabte und ehrgeizige jungen Leute ein erstes eigenes OS zu basteln, um die Grundlagen besser zu verstehen - zur Verfügung haben, nämlich einen 80x86 Rechner mit MS Windows. Daher schreibe ich das Tutorial in deutsch und starte von diesem Bezugspunkt.
Das Design-Thema habe ich auf Teil 3 verschoben. Teil 2 ist zunächst noch dem spielerischen Kennenlernen weiterer notwendiger Techniken wie Speichermanagement (Paging, Heap, Virtual File System, Ram Disk) und Prozessmanagement (Multitasking) gewidmet. Das Thema User-Lib und -Programme gehört dort auch noch dazu.
Wie ich GRUB und Cross-Compiler einbeziehen werde, weiß ich noch nicht sicher. Zunächst werde ich das Community-OS tyndur näher unter die Lupe nehmen, um handwerklich dazu zu lernen. Hier existiert ein "noch" lebendiges deutsches Forum zum Thema OS Development, das eine Unterstützung/Belebung verdient und arbeitsteilig seit einigen Jahren ein interessantes Hobby-OS entwickelt:
http://lowlevel.brainsware.org/wiki/index.php/TyndurDas Kernproblem für den Einsteiger ist nicht die komplexe x86-Technik, die in den Intel Manuals gut beschrieben ist, sondern die Herausforderung, mit den notwendigen Tools (Intel- und AT&T Assembler-Syntax, Linker-Skripte, Cross Compiler, GRUB Image, Bochs Debugger, ...) und Informationsquellen (Intel Manuals, Foren, Tutorials, Bücher, Sourcecode einiger Vorbild-OS, Wechselspiel C und Assembler, ...) umfassend und tiefschürfend klar zu kommen.
Minix3 http://www.minix3.org/ spielt hierbei nach wie vor nur eine akademische Rolle als Beispiel für einen "Mikrokernel", was nichts über seine Bedeutung für die Zukunft aussagt. Es wurde historisch schlicht und einfach von Linux besiegt. Hier hat der mutige Student über den sturen Professor gesiegt.
In der Praxis findet man momentan bevorzugt monolithische Systeme.
-
Erhard Henkes schrieb:
Das Kernproblem für den Einsteiger ist nicht die komplexe x86-Technik, die in den Intel Manuals gut beschrieben ist...
x86 prozessoren sind schon übel genug. protected/real-mode, descriptortabellen, segmentregister usw. kommen doch nur daher, dass eine uralt-cpu mit immer mehr funktionalität versehen wurde, aber trotzdem kompatibel zur ursprungsversion bleiben sollte. hinzu kommt noch die hürde der verfrickelten PC-architektur (boot-loader, bussysteme, video-ram, bios, usw). alles in allem eine suboptimale konstruktion, so als hätte jemand einen formel-1 wagen aus 'nem trabbi zusammengezimmert.
Erhard Henkes schrieb:
sondern die Herausforderung, mit den notwendigen Tools (Intel- und AT&T Assembler-Syntax, Linker-Skripte, Cross Compiler, GRUB Image, Bochs Debugger...
hier bietet sich vielleicht an (als unterprojekt z.b.) eine toolchain zusammenzustellen, die ein benutzer leicht installieren (oder im idealfall einfach auf seinen rechner kopieren) kann, um dein OS zu bauen, zu testen und damit zu experimentieren.
Erhard Henkes schrieb:
"Mikrokernel", was nichts über seine Bedeutung für die Zukunft aussagt. Es wurde historisch schlicht und einfach von Linux besiegt.
...
In der Praxis findet man momentan bevorzugt monolithische Systeme.auch hier, würde ich sagen, hat nicht das bessere gesiegt. ein modularer kernel ist doch wartbarer und leichter erweiterbar, als ein monolithischer klotz. ein system, in dem alle komponenten über wohldefinierte schnittstellen verbunden sind, ist im endeffekt auch weniger komplex.
-
x86 prozessoren sind schon übel genug. protected/real-mode, descriptortabellen, segmentregister
Wenn man die Beiträge zu der "üblen" Situation der x86 Architektur liest, fragt man sich, warum diese komplizierte Struktur - bedingt durch Abwärtskompatibiltät - nicht schon längst durch eine überlegene einfachere Struktur überholt wurde?
toolchain
Ja, das ist richtig. Langfristig bleibt aber einem "OSDever", der in einer OS-Entwickler-Community (Deutschland: lost/tyndur; lowlevel.brainsware.org) eingebettet sein will, nur der Weg über Linux als Hostsystem und GRUB als luxuriöser Bootloader. Das gilt neben Bochs als Emulator und Debugger als Quasi-Standard im PC-Bereich. Linux ist insgesamt ein übermächtiges Vorbild für die gesamte Szene, die alles andere an die Wand drückt. Das ist schade und sollte durchbrochen werden. Vielleicht schaffen wir das noch, sind ja erst ganz am Anfang. Eine OS benötigt Jahre bis ein halbwegs stabiles Team mit Freude daran arbeiten kann. Redesigns und Neuanfänge inbegriffen.
auch hier, würde ich sagen, hat nicht das bessere gesiegt. ein modularer kernel ist doch wartbarer und leichter erweiterbar, als ein monolithischer klotz. ein system, in dem alle komponenten über wohldefinierte schnittstellen verbunden sind, ist im endeffekt auch weniger komplex.
Akzeptiert. Welches Vorbild schwebt Dir hier vor? Minix3?
-
Ich denke mal, es soll dazu dienen, zu verstehen, wie ein OS funktioniert. Deswegen wird es von Grund auf programmiert. Und da so etwas nicht einfach ist, muss man etwas Geduld mitbringen.
Ja, Geduld und die Bereitschaft tief zu bohren, gehören dazu. Ich denke, dass so etwas lange Zeit braucht, bis es "fliegt".
Dann gibt es allerdings ein anderes Problem, nämlich Einsteigern in die Materie die Zusammenhänge darzustellen. Beispielsweise ist es extrem schwierig in "tyndur" (lost) einzusteigen, weil nirgends eine didaktisch durchdachte Step-by-Step-Anleitung, Modul-/Funktions-Übersichten oder grafische Darstellungen zu finden sind, wie dieses OS im Inneren arbeitet. Man muss über die ganz harte Tour zum Insider werden oder man lässt es schnell wieder.Auf jeden Fall werde ich den Noobie nicht aus den Augen verlieren. Ein Buch "Betriebssystementwicklung - leicht gemacht" ist ein mögliches Ziel, oder zumindest eine brauchbare Tutorial-Reihe. Der Brückenschlag zu den Hobby-Robotern bietet sich ebenfalls an. Microsoft hat mit "Robotics" (seit 2006) http://msdn.microsoft.com/de-de/robotics/default(en-us).aspx einen Anfang gemacht. Daneben ist aber noch viel Platz für Alternativen.
Bisher haben wir nur einige "Bausteine" gezeigt und etwas damit herum experimentiert. Immerhin habe ich bereits argumentativ mit geholfen, dass James Molloy einsieht, dass er seine Tutorial-Reihe komplett überarbeiten sollte.
-
Erhard Henkes schrieb:
Wenn man die Beiträge zu der "üblen" Situation der x86 Architektur liest, fragt man sich, warum diese komplizierte Struktur - bedingt durch Abwärtskompatibiltät - nicht schon längst durch eine überlegene einfachere Struktur überholt wurde?
schwer zu sagen. wahrscheinlich sinds wirtschaftliche interessen, an denen sich hard- und softwarehersteller ständig gegenseitig hochziehen. warum eine etablierte technik über den haufen werfen, wenn man einfach was dranflicken und der kundschaft als innovation verkaufen kann? solange der geldhahn sprudelt, besteht kein grund für 'ne radikale änderung, ja es wäre sogar riskant.
Erhard Henkes schrieb:
Welches Vorbild schwebt Dir hier vor? Minix3?
nix konkretes, einfach nur ein gutes, modulares design. klare trennung der aufgaben, hardwareabstraktion, schichtenmodell usw.
-
einfach nur ein gutes, modulares design. klare trennung der aufgaben, hardwareabstraktion, schichtenmodell usw.
Schichtenmodell:
http://www.oser.org/~hp/sys_mgm/node4.html
http://de.wikipedia.org/wiki/Schichtenarchitektur#Schichtenmodell_bei_Betriebssystemen
Die Kommunikation muss über die Schnittstellen jeder einzelnen Zwischenschicht erfolgen. Das kostet Zeit und ist der Preis dieser sauberen Architektur.Damit fiele Minix3 als puristischer Microkernel weg, wenn ich das richtig sehe.
-
Erhard Henkes schrieb:
Die Kommunikation muss über die Schnittstellen jeder einzelnen Zwischenschicht erfolgen. Das kostet Zeit und ist der Preis dieser sauberen Architektur.
sowas lässt sich sowieso kaum verhindern, beispiel: filesystem->sektorbasierter zugriff->bustreiber->hardwaretreiber, oder netzwerk->transport protokoll->paketorientierter zugriff->hardwaretreiber, usw. hauptsache verschiedene teilkomponenten sind dabei austauschbar bzw. parallel ausführbar (z.b. ein filesystem kann gleichzeitig mit festplatten, sd-karten und cd-roms arbeiten, was ja unter allen grossen OS selbstverständlich ist).
Erhard Henkes schrieb:
Damit fiele Minix3 als puristischer Microkernel weg, wenn ich das richtig sehe.
kommt drauf an, hauptsache die architektur bleibt flexibel. vielleicht ein 'hybridkernel' wie windows oder so: http://en.wikipedia.org/wiki/File:Windows_2000_architecture.svg
-
Ich habe hier ein Kapitel zum Thema "Aufruf einer C-Funktion" geschrieben:
http://www.henkessoft.de/OS_Dev/OS_Dev2.htm#mozTocId342494Vielleicht könnte mal jemand drüber schauen, ob Fehler/Unklarheiten enthalten sind.
-
Erhard Henkes schrieb:
Vielleicht kann man mal jemand drüber schauen, ob Fehler/Unklarheiten enthalten sind.
Vielleicht wäre es noch wichtig zu erwähnen, dass es bestimmte Aufrufkonventionen gibt, wie cdecl, stdcall, pascal und fastcall (gibt es noch welche?) und dass damit geregelt wird, wie die Parameter auf dem Stack abgelegt werden, also in welcher Reihenfolge, und wer sie aufräumen muss (caller oder callee)...
-
Erhard Henkes schrieb:
Vielleicht kann man mal jemand drüber schauen, ob Fehler/Unklarheiten enthalten sind
du solltest noch dazuschreiben, auf welchen compiler du sich beziehst (GCC version 4.x nehme ich an) ein anderer compiler könnte vieles anders machen. ach ja, die benamung der funktion 'exit_task()' finde ich nicht sonderlich gelungen. dem namen nach könnte man vermuten, dass die funktion die task beendet, so dass sie nicht wieder dran kommt (vergl. exit() in standard C). womöglich wäre next_task(), switch_now(), yield(), oder sowas eine alternative?
-
'exit_task()' finde ich nicht sonderlich gelungen
Ja, das ist eindeutig falsch. "switch_context()" klingt gut, hat vor allem keinen Bezug zu irgendwelchen POSIX-Begriffen. Normalerweise machen Prozesse so was nicht "freiwillig", nur Threads kennen yield(). Da jede task ihren eigenen Adressraum hat, handelt es sich eindeutig um Prozesse. Das Ganze ist noch relativ experimentell und rudimentär. Ich denke gerade über eine vernünftige Weiterentwicklung nach, aber vielleicht ist es an dieser Stelle dafür noch zu früh, denn Scheduling und Threading ist ein zwar wichtiges aber leider ebenso komplexes Thema mit vielen Möglichkeiten. Das Schlimme dabei ist, dass es keine optimale Lösung gibt. Selbst Linux hat hier im Laufe seiner Entwicklung einen vollen Salto hingelegt. Das Thema Deadlock und entsprechende Deadlock-Algos zur Vermeidung oder Vorbeugung lauert bei Multithreading ebenso bereits um der Ecke.
GCC version 4.x nehme ich an
Das ist ein ganz übles Thema, da ich wegen des eigenen Bootloaders und dieses blöden aout-Formats (16/32-Bit-Code gemischt in kernel.asm) beim Linker immer noch an die Version gcc 3.1, ld 2.13 (in DJGPP) gebunden bin.
Hier hilft - nach meinem bisherigen Wissensstand - nur der typische Ausstieg nach Linux und GRUB. Dies werde ich in Teil 3 wohl auch machen müssen. Dann kommen allerdings die ganzen GRUB-Themen (magic numbers, ...) hinzu. Jemand, der auf längere Sicht OS-Development betreibt, muss sich allerdings diese Tool-Basis schaffen, um fremde OS kompilieren/testen zu können.
-
Bin in dem neuen Artikel nur über eine eher unwesentliche Kleinigkeit gestolpert:
Es gibt übrigens eine Konvention, dass der callee bevorzugt die Register EAX (z.B. zum Rechnen, Transferieren und als Rückgabewert), ECX (z.B. als Schleifenzähler) und EDX (in obigem Bsp. z.B. zum Rechnen) verwendet.
Das ist weniger eine Konvention sondern mehr eine Vorgabe des Prozessors. Manche Instruktionen arbeiten nur mit bestimmten Registern. "LOOP" als Beispiel funktioniert nur mit ECX als Zähler.
-
dat is ne konvention. du musst eax ja ned als rückgaberegister nehmen oder ecx für die l00ps etc. das is schon richtig so wie es da steht.
-
http://de.wikipedia.org/wiki/Aufrufkonvention#stdcall
http://www.agner.org/optimize/calling_conventions.pdf (Kap. 6, Register Usage)Ich habe diese beiden Links in den Artikel übernommen. Danke für die Durchsicht.
-
Eine Frage zum Artikel hätte ich da noch:
Warum ist in dem Beispiel der Wert vom ESP so extrem groß (0x40205xxx), aber der vom EIP (0x00009Cxx) so niedrig ?
-
warum nicht? was hat der 1 mit dem anderen zu tun?
-
Speichermanagement ? Virtualisierung ? Noch mehr ?
-
häh? ich kenn jetzt erhards OS nicht aber wenns generell gemeint ist versteh ich dein posting nicht. er kann doch die dinge mappen wo er will
-
Erhard Henkes schrieb:
Hier hilft - nach meinem bisherigen Wissensstand - nur der typische Ausstieg nach Linux und GRUB.
das wäre doch doof. die meisten haben windosen. sich extra noch ein OS zu installieren, um dein OS zu bauen, ist nervig.
Erhard Henkes schrieb:
Dies werde ich in Teil 3 wohl auch machen müssen. Dann kommen allerdings die ganzen GRUB-Themen (magic numbers, ...) hinzu. Jemand, der auf längere Sicht OS-Development betreibt, muss sich allerdings diese Tool-Basis schaffen, um fremde OS kompilieren/testen zu können.
es geht bestimmt mit jedem compiler z.b. msvc express edition, watcom, oder dem LCC. natürlich nicht von allein, etwas basteln muss man schon. vorteil: du wärst diese ätzende AT&T-syntax endlich los.
-
Erhard Henkes schrieb:
Das ist ein ganz übles Thema, da ich wegen des eigenen Bootloaders und dieses blöden aout-Formats (16/32-Bit-Code gemischt in kernel.asm) beim Linker immer noch an die Version gcc 3.1, ld 2.13 (in DJGPP) gebunden bin.
Hier hilft - nach meinem bisherigen Wissensstand - nur der typische Ausstieg nach Linux und GRUB.Wieso muss es eigentlich im aout Format sein? Ich habe vor kurzem das OS + Bootloader unter Ubuntu 9.04 mit recht aktuellem gcc 4.3.3, ld 2.19.1 und nasm 2.05.1 compiliert. Dabei habe ich unter anderem das aout in elf geändert, und es lief ohne Probleme. Das aktuelle DJGPP hat ähnliche Versionen, daher sollte das doch eigentlich auch gehen, oder gibt es da noch einen anderen Unterschied?
Im NASM Manual steht auch, wenn ich das richtig verstehe, dass 16 Bit im ELF Format möglich ist, da NASM die nötigen Informationen übergibt, damit ld weiß was damit zu tun ist: http://www.nasm.us/doc/nasmdoc7.html (7.7.6)
Unter http://pastebin.com/m3b4d8bcd ist mein Makefile. Das Basis Makefile war die aktuelle Testversion am 20. Mai. Ansonsten habe ich nur noch bei sämtlichen Variablen und Funktionen, die von c benutzt wurden, aber in asm definiert waren, den Unterstrich entfernen müssen. Anscheinend ist es nicht mehr Standard, dass gcc den Unterstrich benutzt und ich habe auch kein Compilerflag dafür gefunden das wieder zu aktivieren.