Hallo,
Naja, das ist jetzt Definitionssache, was du als OS bezeichnest
Klar, ich meinte das auch nicht so ganz ernst, ich wollte auf die Tatsache hinaus das ein Micro-Kernel bereits zu 100% einsatzfähig sein muss (also IPC, Timing, Speicherverwaltung und Prozess/Thread-Management) bevor auch nur ein Treiber o.ä. geladen werden kann.
Ich meine aber wenn du einen monolithen mit einem mikro vergleichst, dann kann man sagen dass das OS erst läuft wenn alle Server und Treiber laufen und bis dahin ist es dann doch um einiges komplexer bei einem Mikrokernel.
Damit hast Du natürlich recht aber da das alles im User-Mode abläuft kann man da auch einiges tricksen wie z.B. den Boot-Vorgang von einem Script steuern lassen oder über alle verfügbaren CPUs verteilen.
Ich muss mir bei mir nochwas schönes einfallen lassen, da ich auch Hardware habe (Timer) die ihr Arbeit nicht im UserMode sondern im KernelMode verrichten, aber eigentlich wollte ich das die richtigen Treiber dann wirklich nur ne Nachricht bekommen bzw. aufgeweckt werden.
Die einzigste HW die mir da einfällt ist eben der Timer aber auch der wird bei einem Micro-Kernel nur dazu benutzt irgendwelchen User-Mode-Prozessen eine Message zu schicken bzw. Threads aufzuwecken, sollte also auch ziemlich schnell sein.
Also es war wirklich nicht schwierig (mein Kernel war von Anfang an so geplant und das war mit das erste was ich implementiert habe).
Bist Du sicher? Bitte nicht falsch verstehen aber bist Du wirklich sicher das in Deinem Code keine potentiellen Dead-Locks usw. drin sind oder sind die bis her nur nicht aufgetreten? Auf wie vielen CPUs lief Dein Kernel schon? Was denkst Du eigentlich wie viel Performance dieser zusätzliche Code im Kernel kostet und wie viel Performance ein unterbrechbarer Kernel dafür wieder bringt? Ich weiß es nicht genau aber mein Bauch sagt mir das bei einem Micro-Kernel wohl eher der Verlust überwiegen dürfte. In einem Micro-Kernel gibt es IMHO keine Vorgänge die so lange brauchen das man sie unterbrechbar machen müsste oder für die der Kernel eigene Threads braucht.
Ich hoffe wirklich das Dein Kernel so funktioniert wie Du Dir das vorstellst aber ich weiß auch das es da einige sehr spezielle Stolperfallen gibt. Selbst in Linux gab es deswegen schon den einen oder anderen Bug.
Kann sein das ich da anders ticke, aber die Arbeit etwas Multithreading tauglich zu machen ist im Kernel- und UserMode eigentlich gleich.
Nein, da kann ich Dich beruhigen, diesbezüglich tickst Du ganz normal.
und das geht halt wesentlich effizienter wenn man dann die Ints abschalten kann
Sicher? Das würde ich aber doch bezweifeln. Es ist ein Trade-Off aus dem zusätzlichen Aufwand zum Abschalten und Reaktivieren der IRQs (was wohl in >99% aller Fälle unnötig ist da die CPU ja nicht ständig IRQs bekommt) und dem Verlust wenn ein Thread gerade auf einen anderen wartet weil dieser einen Lock hat aber unterbrochen wurde und den Lock daher nicht freigibt. Sicher wird dieser Trade-Off oft zugunsten der abschaltbaren IRQs aufgehen aber das muss nicht zwangsläufig so sein. Wenn man z.B. die IRQs dynamisch über viele CPUs verteilen kann so das die Wahrscheinlichkeit hoch ist das immer eine CPU Zeit hat oder wenn man Hardware benutzt die möglichst viele Jobs auf ein mal selbstständig erledigt und so nur wenige IRQs generiert kann es durchaus sein das dieser Trade-Off in die andere Richtung aufgeht.
Man sollte nichtmal daran denken, das ein UserMode Programm die Möglichkeit hat die Ints abzuschalten, das wäre genauso "dämlich" wie cooperatives-Multitasking. Sicher kann das auch funktionieren, aber einem warum sollte man es einem Programm so leicht machen den PC unbenutzbar zu machen!?
Wo siehst Du das Problem? Auf meiner CPU soll es möglich sein das ein User-Mode-Thread für eine sehr kurze Zeit, z.B. für die nächsten 32 Assemblerbefehle, das annehmen von IRQs blockieren kann. Wenn man dafür seiner aktuellen Restzeitscheibe immer 1ms als Fairness-Ausgleich abzieht dann kann es keine Gefahr geben das so ein Thread den Computer
unbenutzbar macht. Zumal nach Ablauf dieser kurzen Zeitspanne die CPU ja prüfen kann ob IRQs in der Zeit angelaufen sind und diese dann verarbeiten, dadurch erhöht sich höchstens etwas die Latenz. Und da bei mir die IRQs dynamisch, anhand der Prioritäten des gerade ausgeführten Codes, über alle CPUs verteilt werden sollen dürfte es kaum messbar sein wenn ab und an mal eine CPU sich aus diesem Prozess kurz ausklingt, ein Syscall hat die selbe Wirkung weil bei mir ja der Kernel grundsätzlich nicht unterbrechbar ist.
Da mein Kernel schon einige Interfaces hat (weil er aus Modulen besteht die vom Loader zusammengefügt werden), weis ich das ein Interface zwar für einen Programmieren schön ist
Ja ist das denn kein wichtiger Grund? Was macht es schon ob Dein Loader 5 oder 50 Module lädt? Ein sauber programmierter und klar strukturierter Kernel in dem der Programmierer sich gut zurecht findet (der deswegen vielleicht weniger Fehler enthält) ist IMHO sehr viel mehr wert!
wie viele sinnlose Funktionen (z.B. "uint32t foo(void bar) { return 0; }") ich dadurch habe.
Ich weiß ja nicht wie Du Interfaces entwickelst aber solche Funktionen hatte ich noch nie (und wenn doch würde die ein guter Compiler wegoptimieren).
ist eine Regel von mir keine FPU im Kernel
Die armen Kernel-Threads, das empfinde ich schon als erhebliche Einschränkung.
Und genau damit habe ich ein Problem. Wenn man immer darauf bedacht ist kompatibel zu bleiben wird nichts richtiges neues mehr Entwickelt.
Wo wir wieder bei dem Henne-Ei-Problem wären. Wir halten an den ganzen alten Sachen fest und das hindert uns daran was richtig neues zu machen.
Dann kannst Du ja sehr gut nachvollziehen warum ich eine komplett neue Plattform entwickeln möchte. Ich will endlich mal mit ein paar alten Traditionen brechen und beweisen das es auch anders geht.
Wenn Du so denkst, warum programmierst Du dann Dein OS ausgerechnet für x86?
Richtig! Und ich schreibe lieber meinen Kernel neu
Ich schreibe zwar definitiv kein portables OS aber wenn ich es tun würde würde ich mich schon bemühen meine Zeit etwas effizienter zu verwalten. Nimm es mir nicht über aber gleich den ganzen Kernel (und sei es nur ein Micro-Kernel) neu zu programmieren halte ich für reichlich ungeschickt, das geht mit einer guten Modularisierung auf Quell-Code-Ebene deutlich besser.
Grüße
Erik