Also nochmal, der Runtime-Loader läuft weder im Kernel noch ist er Bestandteil des Kernels (er liegt irgendwo dazwischen), er ist ein ganz "normales" Programm (welches keine Libraries bzw. shared-Libaries nutzen darf).
Ist also ein BLOB im Kernel.
Also der Runtime-Loader hat insofern zugriff auf irgendwelche Libraries, wenn er sie statisch mit in die Executeable packt und damit noch weit unter 4MB bleibt.
Also hat er keinen Zugriff auf Libraries. Wenn ich die Bibliothek nicht besuchen darf, habe ich keinen Zugriff darauf, auch wenn ich alle Bücher der Bibliothek selbst besitze und mitnehmen darf.
Ich habe auch desweiteren eine Art exec() Funktion für alle Programme. Diese Funktion führt im Endeffekt mein createEmptyProcess() aus, welche dann den Runtime-Loader "startet". Der wiederum ruft dann den exec-Syscall auf und damit bekommt der aufrufende Prozess nen Rückgabewert und der neue Prozess wird gestartet.
Also hast du in der libc ein exec(), welches den Runtime-Loader in einen neuen Prozess mappt und startet, und du hast einen Syscall Exec, der den Runtime-Loader aus einem Prozess entfernt und ihn resettet (diesmal an der realen Position).
Was besser ist, weiß ich nicht. Ich halte meinen Ansatz für flexibler.
Wo siehst du deinen Ansatz flexibler und wo meinen unflexibel?
Es gibt nur einen Runtime-Loader, der ist Teil des Kernels (wenn er auch nicht als solcher ausgeführt wird). Damit ist er prinzipiell nicht ersetzbar. Du hast einen speziellen Exec-Syscall für den Runtime-Loader, den auch nur dieser nutzen kann, und es gibt keine andere Möglichkeit, einen Prozess zu erzeugen.
Dein Kernel ist nicht in der Lage, Prozesse zu starten, ohne ein Dateisystem und die dazugehörigen Services geladen zu haben. Außerdem kannst du keine Prozesse starten, wenn der Runtime-Loader defekt ist oder ersetzt werden muss. Ich find das alles nicht so pralle, aber funktionieren dürfte es.
Der Runtime-Loader ist bei mir kein Teil des Kernels, sondern eine Anwendung wie jede andere auch, mit dem Unterschied, dass sie keinen Runtime-Loader benötigt, sondern bereits im kernel-nativen Binärformat vorliegen muss. Es gibt also ein Format, welches der Kernel ausführen kann und darauf kann der Runtime-Loader später aufbauen.
Und genau hier finde ich meinen Ansatz besser bzw. könnten die auch gleich sein/gemacht werden.
Das hatte ich erwähnt, als ich meinte, der Kernel könnte das ELF auch direkt parsen und alle anderen Dinge laufen durch den Runtime-Loader.
Denn mein Runtime-Loader liegt auf der Platte als normale ELF-Datei vor, ist also ein Programm wie jedes andere auch (theoretisch, praktisch würde sich der Runtime-Loader sofort wieder beenden und nichts tun, wenn man ihn ausführt).
Wer parst den Runtime-Loader, wenn der eine ELF-Datei ist? Tut es der Kernel selbst, brauchst du keinen Runtime-Loader mehr für ELF-Dateien und andere Formate kannst du komplett im Userspace implementieren.
Der Linux-Runtime-Loader gehört zur libc(!) und wenn du ihn startest, kannst du damit ELF-Dateien ausführen. Und zwar so, als ob du sie direkt ausgeführt hättest.
In meinem Bootskript steht halt welche Datei der Kernel ist und welche Module noch geladen werden sollen und ich würde jetzt noch ein paar weitere Punkte (Runtime-Loader, Storage-Server, Device-Server, TUI-Server) hinzufügen.
Geladen werden nur die, die für den Bootvorgang auch benötigt werden, sprich der TUI-Server wird erst später vom Storage-Server geladen, aber ich möchte in diesem Bootskript schon alle wichtigen Server drin haben.
Halte ich für den falschen Ansatz. Du möchtest dem Bootloader nicht
alle Server mitgeben. Möchtest du nicht. Ist einfach falsch. Du möchtest im Betrieb neue Server definieren können. Server sind bei dir ganz normale Anwendungen mit ein paar Eigenheiten. Warum die im Bootloader statisch definieren?
Warum (und woran) sollte der Bootloader entscheiden, welche Server geladen werden müssen und welche nicht? Können die Server das nicht selbst entscheiden? Was passiert, wenn die Autodetection fehlschlägt?
Warum sollte der Storage-Server den TUI-Server laden? Die haben nichts miteinander zu tun. Der TUI-Server sollte vom Kernel (oder von mir aus dem Servermanagement-Server) geladen werden, wenn eine Konsole daran gebunden werden soll.
Was interessiert es den Bootloader, ob der App-Server dabei ist? Fehlt am Ende des Tages der App-Server, gibts eine Kernel-Panic und gut ist.
Weil es den Kernel einfacher und kompakter macht. Warum muss der Kernel nachgucken ob alles im Bootskript stand? Ich kann doch schon im Bootloader so viele Fehler wie möglich ausschließen ohne das System überhaupt geladen zu haben.
Der Bootloader soll dem Kernel nicht vorschreiben, was er wie zu tun hat. Der Bootloader soll den Kernel laden und starten und mehr nicht (zumindest ist das meine Definition).
Gedankenspiel: Jeder Server, der gestartet wird, registriert sich beim Kernel. Der App-Server (egal, welcher es ist) registriert sich als "APP". Wenn der Kernel jetzt darauf zugreifen möchte, dann ruft er über IPC nach einem Server mit dem Namen "APP". Ist keiner da: Panic. Damit kannst du im Betrieb den App-Server ändern (oder neustarten), ohne den gesamten Kernel neustarten zu müssen.
Bei dir muss man also, um einen Server zu registrieren, das System neustarten und zerschießt sich unter Umständen die Bootkonfiguration.
Ich halte das für nicht sinnvoll, aber diskutiere nicht weiter. Mach es, wie du es für richtig hältst.
Um es mal auf die Spitze zu treiben, du erwartest doch auch das alle Treiber geladen werden, für die Geräte die vorhanden sind und nicht erst geguckt wird ob ein Gerät vorhanden ist, wenn es vllt irgendwann mal benutzt wird.
Erstmal gibt es zwei Treiber. Einmal den hardwarespezifischen Treiber, der die Hardware ansteuert, und einmal einen allgemeinen Treiber, der mit den Anwendungen und dem hardwarespezifischem Treiber redet.
Konkret ein AC97-Treiber und ein Audio-Server. Letzterer stellt für Anwendungen eine definierte API für Mixer, Kanäle und so weiter zur Verfügung, kann Mischen und Remixen und was-auch-immer. Das kann man als Userspace-Programm (wie PulseAudio) lösen, halte ich aber nicht für sinnvoll, weil es an sich eine Kernfunktionalität von Betriebssystemen ist. Stecke ich jetzt meine USB-AC97-Soundkarte(*) dort an, wird der AC97-Treiber geladen. Fertig.
Der allgemeine Audio-Server wird nicht gestartet. Wenn eine Anwendung Audio ausgeben möchte, macht sie eine Anfrage (z.B. open /dev/audio). Diese Anfrage startet den Audio-Server und er schaut, welche Treiber vorhanden sind und gibt den Ton aus. Anschließend wird er wieder beendet. Die Treiber halten die Hardware ununterbrochen im Stromspar-Modus, solange sie niemand benutzt.
Gut, Audio ist da nicht unbedingt das beste Beispiel, weil man es ständig benutzt, aber für Bluetooth, UMTS oder WLAN ist das schon wesentlich sinnvoller. Außerdem verkürzt das die Bootzeit, weil Server erst gestartet werden, wenn die entsprechenden Anwendungen laufen.
(*) Ja ich weiß, sowas gibt es nicht.
Was die Services betrifft, hängt das auch einfach vom Umfang ab, wenn ich dann 1min zum Starten des Services brauche, dann werden >90% der Nutzer sagen, lieber von Anfang an laufen lassen, als jedes Mal 1min zu warten bis ich es benutzen kann.
Meine Lösung schließt ja nicht aus, dass es persistente Services geben kann. Aber sie macht es möglich, dass dem nicht so ist. Und man könnte es von externen Ereignissen abhängig machen (im Akkubetrieb sind alle Services "aus", im Netzbetrieb sind sie "an").
Da hast du jetzt einen Denkfehler drin. Das einzige was du sparen kannst ist RAM! Denn wenn der Server nicht benutzt wird, läuft er auch nicht, er wartet das eine Anfrage an ihn gestellt wird und das kostet keine CPU-Zyklen.
Er muss aber gestartet und verwaltet werden. Und der Start eines Servers kann recht teuer sein.
Aber wir driften ab, ich denke, wir werden uns da wieder nicht einigen können, daher lass ich es.
Gruß,
Svenska