Autor Thema: Doku tyndur  (Gelesen 27060 mal)

ehenkes

  • Gast
Gespeichert
« am: 27. May 2009, 23:39 »
Wo finde ich eine ausfuehrliche Hintergrund-Dokumentation fuer tyndur? Was sind die grundsaetzlichen Design-Prinzipien dieses OS?
« Letzte Änderung: 27. May 2009, 23:52 von ehenkes »

stultus

  • Beiträge: 486
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 28. May 2009, 16:05 »
Trial & Error ;)

Richtige Design-Dokus gibts bislang leider nicht. Wenn du was spezielles Wissen möchtest, schau einfach im IRC vorbei (oder frag hier, aber dann brauch das mit der Antwort womöglich länger ;)).
MSN: planetconquestdm@hotmail.de
ICQ: 190-084-185

... Wayne?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 28. May 2009, 18:40 »
Im Wiki gibts einen spannenden Artikel, der demnächst auch verfilmt wird.
Dieser Text wird unter jedem Beitrag angezeigt.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 28. May 2009, 20:34 »
Ich weiß schon wer die Roadmap das Drehbuch schreibt. :-D  :mrgreen:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

ehenkes

  • Gast
Gespeichert
« Antwort #4 am: 30. May 2009, 15:04 »
wiki artikel ist ein guter einstieg. die design prinzipien (z.B. gemaess tanenbaum, modern os, 3rd ed.) werden aber IMHO nicht ausreichend ausfuerlich erklaert. der begriff rpc sollte verlinkt werden.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 30. May 2009, 17:33 »
Ich habe bis jetzt mehr Text von Torvalds als von Tanenbaum gelesen und weiß insofern auch nicht, was letzterer genau unter Designprinzipien versteht (von ersterem weiß ich es übrigens auch nicht). Ich habe auch nicht unbedingt vor, das Buch jetzt extra zu kaufen. Vielleicht solltest du daher deine Frage etwas detaillierter und ohne Bezug auf andere Quellen formulieren, wenn du die Antwort erhalten möchtest, die du suchst.

Je nachdem du den traditionellen kernel in tyndur anschaust oder was kernel2 mal werden soll, gibt es natürlich auch Unterschiede. Die aktuelle Implementierung von kernel2 liegt irgendwo dazwischen drin.

Beim Design kann man in einem Kernel wohl auf zwei verschiedene Dinge abheben: Einmal auf die innere Struktur, die verschiedenen Einheiten, die zusammen den Kernel bilden; zum anderen die Schnittstelle zu den Userspace-Programmen, also die Syscalls.

Fangen wir mal mit dem ganz grundsätzlichen an: tyndur benutzt einen Mikrokernel, Hardwaretreiber laufen üblicherweise als ganz gewöhnliche Userspace-Prozesse. Die drei großen Einheiten im Kernel sind, wie ich das auch im Einführungsartikel im Wiki dargestellt habe, die Speicherverwaltung, Prozessverwaltung und IPC. Dazu kommen natürlich noch so Geschichten wie Low-Level-Interrupthandling und Verwaltung der IO-Ports, also Zeug, was direkt Einfluss auf die CPU hat.

Die Speicherverwaltung benutzt auf i386 (kernel2 sieht theoretisch auch andere Architekturen vor) die hier üblichen und als richtig dargestellten Mechanismen. Speicherschutz wird über Paging erreicht, jeder Prozess hat seinen eigenen Speicherkontext, und Segmentierung wird nicht benutzt.

Die Prozessverwaltung macht nichts aufregendes - sie verwaltet eben Tasks. In kernel gibt es nur Prozesse, kernel2 kann auch Threads. Der Scheduler ist eine einfache Round-Robin-Variante. Der Kernel läuft in Ring 0, die Tasks in Ring 3. Ring 1 und 2 sind wie üblich unbenutzt.

Etwas interessanter ist vielleicht die IPC, bei einem Mikrokernel ist es ja nicht ganz unwichtig, wie die Prozesse miteinander kommunizieren. Hier sind zwei Möglichkeiten unterstützt, zum einen Shared Memory und zum anderen RPC. RPCs sind asynchron und können Daten als Parameter enthalten. Für den aufgerufenen Prozess sieht das ähnlich aus wie ein Signal unter *nix: Er wird unterbrochen, wo er gerade ist, bekommt die RPC-Daten auf den Stack gepackt und macht mit seinem RPC-Handler weiter. Wenn er fertig ist, springt er wieder zurück, wo er herkommt. Damit in kritischen Abschnitten nichts böses passiert, kann der RPC-Empfang auch blockiert werden.

Das war's eigentlich schon, was die zentralen Themen angeht. Vielleicht noch einen Blick auf die List der Syscalls. Viel aufregendes ist dort nicht zu sehen, mehr oder weniger sind das die erwarteten Funktionen für den beschrieben Umfang. Was vielleicht noch interessant ist, ist der Start von Programmen und das Interrupthandling.

Der Loader für die Programme sitzt ebenfalls im Userspace und zwar momentan in init. Was der Kernel bereitstellt ist eine Funktion, um einen "leeren" Task zu erstellen. Der Loader lädt anschließend das Programm erst einmal in seinen Speicher und tritt die entsprechenden Pages dann an den neuen Task ab. Wenn er damit fertig ist, lässt er ihn loslaufen.

Für Hardware-Interrupts registriert sich der Treiber beim Kernel als zuständig. Wenn die Hardware jetzt einen IRQ feuert, sendet der Kernel einen RPC an den Treiber, der die passenden Maßnahmen ergreift, gleichzeitig sendet er aber auch ein EOI an den PIC. Damit der Interrupt nicht sofort wieder feuert, wird er maskiert. Erst wenn der Treiber aus dem RPC-Handler zurückkehrt und damit den Grund für den Interrupt hoffentlich behoben hat, wird der Interrupt wieder demaskiert.

Ansonsten könnte man zu LostIO, dem VFS, auch noch ganze Romane schreiben. Es spielt eine ziemlich zentrale Rolle, weil in tyndur sehr viel über das Dateisystem läuft. Momentan ist es komplett im Userspace (wird über RPCs implementiert), wandert aber in Zukunft als letztendlich fast wichtigste IPC-Variante in tyndur nach kernel2.

Soweit mal ein grober Überblick. Was fehlt dir noch? ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #6 am: 30. May 2009, 23:04 »
Danke, das ist genau das, was ich suche. Kannst Du noch etwas ueber pmm, vmm, swapping, heap etc. sagen? Warum ist die Speicherverwaltung im Kern? Bei MINIX z.B. im user space.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 30. May 2009, 23:38 »
Naja, tyndur ist nicht so aufgebaut wie es ist weil ich ein überzeugter Mikrokernelverfechter wäre, sondern weil es uns damals praktisch erschienen ist, um saubere Schnittstellen zu kriegen und damit letztendlich besser im Team dran gearbeitet werden kann. Heute sehe ich das etwas anders, aber der Vorteil mit den klaren Einheiten bleibt trotzdem. Und das zieht sich eigentlich so durch: Wir haben das gemacht, was uns praktisch erschienen ist oder einfach genug war. Und Speicherverwaltung im Kernel kommt mir einfach wesentlich unproblematischer vor als extern.

Das physische Speichermanagement basiert auf einer Bitmap. Das virtuelle besteht halt aus dem Paging-Code wie du ihn sicher auch selbst hast. Interessanter würde das werden, wenn man tatsächlich mal Swapping einbaut, aber das haben wir noch nicht. Für malloc/free haben wir mehrere Implementierungen, die seit längerem benutzte und stabile ist liballoc. Dabei gibt es vielleicht noch zu sagen, dass wir keinen Heap im UNIX-Sinn mit brk/sbrk haben, sondern einzelne Pages beim Kernel anfordern.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #8 am: 31. May 2009, 18:53 »
Zitat
Speicherverwaltung im Kernel kommt mir einfach wesentlich unproblematischer vor als extern.
Sehen wohl die meisten so, aber bei einem Hobby-OS koennte man auch momentan noch ineffiziente Designziele verfolgen.

Wie sieht es mit Copy-on-write - analog Linux - und eingeblendeten Dateien aus? Wie mit POSIX? Gibt es bei der zukuenftigen Thread-Verwaltung auch das pid = clone(...) von modernem Linux (seit dem Jahr 2000)?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 31. May 2009, 23:55 »
Zitat
Speicherverwaltung im Kernel kommt mir einfach wesentlich unproblematischer vor als extern.
Sehen wohl die meisten so, aber bei einem Hobby-OS koennte man auch momentan noch ineffiziente Designziele verfolgen.
Ich meinte auch mehr vom Entwicklungsaufwand. Was die Performance angeht, kann man natürlich auch mal eine interessantere, aber langsamere Variante wählen. Aber ganz ehrlich: Einen gcc am Laufen zu haben und ihn trotzdem kaum benutzen zu können, weil I/O so langsam ist, nervt schon tierisch, auch wenn es nur ein Hobby-OS ist.

Zitat
Wie sieht es mit Copy-on-write - analog Linux - und eingeblendeten Dateien aus? Wie mit POSIX? Gibt es bei der zukuenftigen Thread-Verwaltung auch das pid = clone(...) von modernem Linux (seit dem Jahr 2000)?
Naja, erstmal sollte man festhalten, dass tyndur insbesondere aus Kernelperspektive kein Unix ist. POSIX-Funktionen werden teilweise in den Userspace-Bibliothek bereitgestellt und eben mit den nativen Funktionen emuliert.

fork() (und damit letztendlich auch clone()) ist ein ziemlich unixspezifisches Konzept, das in die native tyndur-Welt nicht reinpasst. Nur ein Beispiel, warum das nicht so richtig klappen kann: Der tyndur-Kernel hat keine Ahnung, welche Dateien ein Prozess geöffnet hat. Das Dateisystem läuft komplett im Userspace ab. Dateideskriptoren klonen wird da für den Kernel schwer.

Bei eingeblendeten Dateien sehe ich im Moment nicht den großen Nutzen, könnte man aber wohl irgendwie über Shared Memory machen. CoW kann unter Umständen auch Sinn ergeben, gab bislang aber ebenfalls keinen Bedarf dafür. Bei diesen zwei Dingen würde ich sagen, sie werden implementiert, wenn sie jemand (du?) für wichtig genug hält, es zu machen - und sonst eben nicht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #10 am: 01. June 2009, 17:03 »
Danke fuer die ausfuehrlichen Antworten. Ich werde mir tyndur intensiver anschauen.  :-)

PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #11 am: 30. April 2011, 00:14 »
Moin

Sorry das ich diesen Thread nochmal wieder aufwärem aber ich hab da mal ne kleine Frage.

fork() (und damit letztendlich auch clone()) ist ein ziemlich unixspezifisches Konzept, das in die native tyndur-Welt nicht reinpasst. Nur ein Beispiel, warum das nicht so richtig klappen kann: Der tyndur-Kernel hat keine Ahnung, welche Dateien ein Prozess geöffnet hat. Das Dateisystem läuft komplett im Userspace ab. Dateideskriptoren klonen wird da für den Kernel schwer.
LostIOv2 wird soweit ich weiß in den Kernel verlegt, würde dadurch nicht das "Wissen" erlagen was er bräuchte um die Dateidiskriptoren zu clonen bzw. würde sich der Aufwand ein fork() bzw. clone() zu implementieren dadurch nicht nicht stark verkleinern?

PNoob

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 30. April 2011, 14:40 »
Doch, das geht dann.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 30. April 2011, 23:30 »
Dann will ich auch mal ;)

Also, dass der Kernel keine Dateidiskriptoren kennt und daher kein fork() geht ist nur ne faule Ausrede ;) Ich würde es einfach so lösen, dass ein fork() einfach ein RPC an den VFS-Service ist und dieser alles in die Wege leitet.

Was ich aber viel mehr interessiert, ihr habt also euren Loader im UserSpace. Wenn man nur fertig gelinkte Dateien ausführen will kann das so klappen, aber wie wollt ihr shared-Libraries (die zur Laufzeit nachgeladen werden können und lazy-linking) umsetzen?
Daran scheitert nämlich meine Idee irgendwie. Ich möchte es nämlich eigentlich genauso machen, der Kernel kann nur nen neuen leeren Task erstellen und der Loader erstellt dann das Prozess-Image. Soweit kein Problem, aber wie macht dann halt so Dinge wie Plug-ins oder halt lazy-linking (Adresse einer Funktion wird erst aufgelöst, wenn sie auch benötigt wird)?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 01. May 2011, 00:37 »
Ich glaube, ich habe nie behauptet, dass man so etwas wie fork() nicht nachbauen kann. Aber es ist dann eben nicht die native Kernel-API zum Starten eines Prozesses, sondern etwas darauf aufgesetztes.

Und wegen Shared Libs, was spricht dagegen, zur Laufzeit ein paar neue Pages nachzuladen? Ich muss zugeben, dass ich mich damit nicht gut auskenne, aber ein Problem, das die Architektur dabei macht, sehe ich nicht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 01. May 2011, 08:52 »
Das Problem was ich da sehe, ist dass du ja die Symbole von dem Prozess brauchst und wo speicherst du die? Wenn du lazy-linking benutzen willst, muss dann immer auch der Teil, der das kann, vom Loader im Prozess mit gemappt sein, damit er das Symbol auflösen kann.
Der Loader müsste dann auch ein sehr spezieller Prozess sein. Denn er müsste in der Lage sein, die shared-Library zu laden, mehr oder weniger das Image zu erstellen (damit er weiß wie groß das Image ist). Dann muss er sich einen Speicherbereich, der groß genug ist, aus dem eigentlichen Prozess-Adressraum holen (er braucht die genaue Adresse, jenachdem ob du PIC oder relocateable Code nutzt), die Symbole entsprechend auflösen und dann das Image in den Prozess "geben".

Die Symboltabelle würde ich gerne im Prozess selber speichern, aber die sollte dann möglichst für den Prozess read-only sein und die muss dann auch zum Loader.

Was machst du wenn ganz viele Prozesse mit einmal den Loader benötigen (da wäre dann echt mal ein fork() zu gebrauchen)? Lässt du das alles in dem Prozess vom Loader abarbeiten oder wie wollt ihr das lösen?

Ich suche nur Anregungen ;)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 01. May 2011, 10:10 »
Hm, wie wäre es, wenn der Loader selber eine Shared Lib wäre und damit außer beim Prozessstart im Kontext des Prozesses selbst läuft?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 01. May 2011, 11:16 »
Das ist ja das was Linux macht (ld.so).
Nur hast du dann den Loader nicht zweimal, einmal als Programm und einmal als shared-Library?

Zumal das für mich keine Lösung ist (was ja für euch nicht weiter tragisch ist ;)), da ich es mir vorbehalten wollte, den Loader auch per Plug-Ins/Add-ons erweiterbar zu machen (so dass ich mehrere Dateiformate unterstützen kann).

Das wäre ja alles nicht so das Problem, wenn ich den Loader in den Kernel packen würde, aber das will ich halt nicht.

Eine Lösung wäre halt den Loader als einen Server/Service zu implementieren (so wie ihr es im Endeffekt ja schon irgendwie habt) und wenn ein neues Programm gestartet wird, erstellt der Loader praktisch das Image, macht nen Syscall nach der Art createNewProcess(startAddrProcess,startAddrImage,sizeImage) und wenn der Prozess dann mal dynamisch eine shared-Library nachladen will, ruft er eine Funktion auf (unter Linux glaub ich dlopen oder sowas), die in einer Library ist (das wäre der Teil der in jedem Prozess gemappt wäre vom Loader), und diese Funktion übernimmt dann die ganze Kommunikation mit dem Loader:

sagen welche Library, der Loader erstellt dann, soweit es geht, ein Image und sagt der Funktion wie groß das Image ist, die Funktion liefert dann einen Bereich (mit der virtuellen Adresse im Adressraum des Prozesses) zurück, in den dann der Loader das Image "schreiben" kann (und mit Hilfe der virtuellen Adresse kann er auch die Symbole auflösen), dann müsste noch nen Pointer (virtuelle Adresse im Sinne des Prozesses) auf die Symboltabelle an die Funktion zurückgeliefert werden

Könnte funktionieren, erscheint mir im Moment nur nicht sehr performant, aber ich hätte den Loader so als eigentständigen Prozess.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 01. May 2011, 20:13 »
Das ist ja das was Linux macht (ld.so).
Nur hast du dann den Loader nicht zweimal, einmal als Programm und einmal als shared-Library?
Ist das Programm wesentlich mehr als ein dünner Wrapper um die Lib?

Zitat
Zumal das für mich keine Lösung ist (was ja für euch nicht weiter tragisch ist ;)), da ich es mir vorbehalten wollte, den Loader auch per Plug-Ins/Add-ons erweiterbar zu machen (so dass ich mehrere Dateiformate unterstützen kann).
Hm, wo ist das Problem, solange das eine Format, das für die Loader-Plugins benutzt wird, immer geladen ist?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 01. May 2011, 20:30 »
Zitat von: taljeth
Ist das Programm wesentlich mehr als ein dünner Wrapper um die Lib?
Naja, wenn man es hinbekommt.

Man würde dann vom Boot-Loader den Prozess des Loaders erstellen lassen. Dieser würde aus nem Programm, welches eigentlich nur nen Service bereitstellt und ansonsten aus der Library des Loader besteht, zusammengesetzt werden. Soweit so gut. Man könnte dann die Plug-Ins vom Loader selbst laden lassen und die Symbole würde über die Library-Funktionen aufgelöst werden, würde also auch funktionieren. Aber ... wie bekommst du, außer der "Haupt"-Library, die Plug-Ins in die anderen Prozesse (die normale würdest du dort reinbekommen, indem ja alle Libraries, die benötigt werden, auch geladen werden, aber die Plug-Ins tauchen ja nicht als Library irgendwo auf)?

 

Einloggen