Autor Thema: runtime loader - Programme laden/ausführen  (Gelesen 9840 mal)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 29. December 2010, 18:47 »
Warum sollte es eine andere Möglichkeit geben einen Prozess zu erzeugen bzw. was unterscheidet meinen Runtime-Loader in dem Fall von dem von Linux (vorallem hat Linux eigentlich 2, einem im Kernel und einen in der libc)?
Du musst allgemeine Prozesse erzeugen können, für die du vollständigen Userspace nutzen kannst (Unix-Prinzip ist fork()), aber du brauchst eine minimale Möglichkeit, Prozesse ohne Unterstützung starten zu können. Für dein Mikrokernelkonzept sind das im Speziellen die Services, die dir erst den Userspace geben.

Linux kann nativ ELF ausführen, der Runtime-Loader ist für den Userspace da.

wenn der Runtime-Loader unter anderen OSs defekt ist, können auch keine Prozesse mehr gestartet werden (Vergleich: wenn dein Auto kaputt ist, kannst du solange damit nicht fahren bis es wieder in Ordnung ist).
Ja. In einem Mikrokernel sollten aber zumindest die Services, die den Userspace überhaupt am Leben halten, auch ohne Unterstützung des Userspace gestartet werden können. (Der Bootvorgang ist eine Ausnahme, weil man dort eine Lebendgeburt machen kann.)

Da frage ich mich dann was sind diese anderen Dinge? Denn was außer der ELF Datei zu parsen (und das Process-Image erzeugen) macht denn der Runtime-Loader noch so?
Er erzeugt nicht nur ein Image für den Prozess, sondern muss auch zusätzlich benötigte Libraries finden, laden und daraus Symboltabellen generieren, die er der dynamisch gelinkte Anwendung mitgeben muss. Außerdem kommen eventuell noch Sicherheitsgedanken dazu, also z.B. eine Festlegung, welche Symbole eine bestimmte Anwendung in einem bestimmten Nutzerkontext sehen/nutzen darf. Da kann man einiges konstruieren.

Das native Kernel-Binärformat kann relativ dumm sein (statisch, keine Abhängigkeiten); im Userspace reicht das nicht - darum nimmt man ja einen Runtime-Loader. Wie du deine Services dort einsortierst, weiß ich nicht; es sind zwar Anwendungen, aber ich (als monolithisch versauter Mensch) trenne die streng vom "richtigen" Userspace.

Zitat von: svenska
Wer parst den Runtime-Loader, wenn der eine ELF-Datei ist?
Habe ich doch geschrieben, das macht mein Bootloader (wo praktisch auch ein Runtime-Loader drin ist).
OK.

Anders gefragt, wenn du die [Server] nicht irgendwo definierst, wer startet die dann und wenn dieser Jemand sie startet wurden sie ja doch irgendwo definiert. Du kannst ja schlecht den Benutzer danach fragen, das würde ja die Server schon vorraussetzen.
Also wenn ich mir die übliche GRUB-Konfiguration anschaue, dann übergebe ich bei Linux das Kernelbinary und eine initrd/initramfs. Alternativ kannst du ELF-Module laden lassen und er sagt dir sogar, wo er sie hingeladen hat.

-- Pseudo-Bootloader-Konfiguration --
KERNEL /boot/kernel
MODULE /modules/appserver
MODULE /modules/deviceserver
MODULE /modules/consoleserver
MODULE /modules/tuiserver
...

Der Kernel startet alle Module, die ihm vorgesetzt wurden. Alle weiteren Services, die nicht boot-kritisch sind, werden später geladen. Was ist daran so schlecht?

Erstmal richtig, aber ich gehe halt davon aus, das z.B. entweder der TUI-Server oder der GUI-Server geladen wird und das muss ja irgendwo in irgendeinem Skript stehen und ich will nicht tausend Skripts haben.
Du brauchst weder TUI noch GUI, solange keine Anwendungen irgendetwas ausgeben möchten. Da du in deinem Konzept IPC benötigst, wenden die Anwendungen (z.B. init) sich an einen well-known-service, der eine Funktionalität bereitstellt. Ist der noch nicht vorhanden, wird er geladen. Schlägt das Fehl, kriegt die Anwendung einen Fehler.

Was du machst, ist trotzdem möglich, aber (für mich) nicht schön.

Jein. Ersten hatten wir es doch schonmal das einen Server zu resetten eher weniger schön ist bzw. bei einigen Sachen wahrscheinlich unmöglich und daher sowieso einen System Neustart erfordert und zweitens rede ich ja nur von den wirklich nötigen Servern. Mit allen anderen Servern habe ich nichts am Hut.
Wenn der Server weg ist, der nötig ist, um ein Binary zu laden, dann ist ein Neustart nötig. Aber um den Bluetooth-Server registrieren zu können, müsste ich ihn bei dir in den Bootloader eintragen (Fehler: System kaputt) und neu starten. Das meinte ich. Wo das nicht mehr geht, geht das halt nicht mehr.

Was du bei der ganzen Sache vergisst (bzw. denke ich das ist deiner Linux Denkart geschuldet ;) ), wenn du einen Service nutzen willst muss dieser auch gestartet sein, sprich wenn du ein "open /dev/audio" machen willst, dann muss das auch vorhanden sein, das ist es aber nur wenn der Server auch gestartet ist, ansonsten gibt es das nicht.
Ich kann auch eine Anfrage an einen Server "SND" machen. Das OS sollte fähig sein, festzustellen, dass es diesen Service nicht gibt und ihn selbstständig nachladen können. Wenn ich in /dev/ eine Datei öffne, die nicht existiert, dann könnte man auch in den vorhandenen Modulen nachschauen, ob ein Modul existiert, welches diese Datei bereitstellt.

Das kann man jetzt so lösen das jedes Programm welches einen bestimmten Service nutzen will, erstmal diesen starten muss und ich denke da sind wir uns beide einig, dass das weniger sinnvoll ist.
Das ist Teil der Serververwaltung, nicht Teil der Anwendung. Richtig.

Ansonsten muss zumindest irgendeine Art Ansprechpartner vorhanden sein, der die Anfrage entgegen nimmt und den Server startet und dann die Anfrage weiterleitet und das wiederrum ist auch nicht wirklich sinnvoll und von Performance will ich erst gar nicht anfangen ;)
Wenn man sich das IPC als eine Art "Bus" vorstellt, dann hast du einen Service-Server, der diesen Bus abhört und weiß, welche Services gerade existieren. Wenn eine Anfrage nach "SND" kommt, es aber kein "SND" gibt, dann blockiert die Anfrage, bis der Service aktiv ist oder wird mit Fehlercode beantwortet, wenn der Server nicht existiert oder nicht gestartet werden konnte.

Das kann ich mir auch im Mikrokernel selbst vorstellen, denn der weiß ja, welche Services existieren.

Zitat von: svenska
Er muss aber gestartet und verwaltet werden. Und der Start eines Servers kann recht teuer sein.
Genau das ist/war doch mein Punkt. Da der Start recht teuer sein kann, werden >90% der Nutzen sagen, das der Server lieber von Anfang an "laufen" soll als das man ihn jedes Mal startet wenn er benötigt wird.
Ja, das hängt aber vom Server ab. Im Übrigen gehöre ich dann wohl zu den 10%, die sagen, dass ein Server, der sehr langsam startet, nicht beim Boot gestartet werden soll, wenn ich ihn nicht benötige.

Wenn er einmal läuft, soll er aber aktiv bleiben.

Dynamisch ladbare Module/Add-Ons. Wie würde man sowas lösen mit nem Runtime-Loader der im UserSpace läuft?

Ich dachte da jetzt daran, das mein Runtime-Loader einfach immer im Adressraum bleibt und einfach als Systempages gekennzeichnet wird und wenn das Programm ein Modul laden will (dlopen() usw.) dann wird einfach der Runtime-Loader wieder "freigegeben" (also als Userpages markiert) und er führt sein dlopen() usw. aus.
Dagegen. Ich würde dlopen() in der libc implementieren und zwar in einer Form, dass der Runtime-Loader selbst diese Funktion benutzen kann, um die Abhängigkeiten aufzulösen. Natürlich muss der Runtime-Loader die Funktion statisch eingelinkt haben (da der Kernel keine dynamischen Dateien ausführen kann).

Sollte man für die Symboltabellen z.B. einen Patricia-Tree nehmen oder einfach nur ein großen Array, was man dann durchgeht? Oder anders gefragt ist Performance beim Symbol-Suchen wichtig und/oder erwünscht (würde ja mit etwas mehr Speicherverbrauch einhergehen)?
Keine Ahnung, nie gehört. Bin kein Informatiker. ;-)

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 29. December 2010, 19:12 »
Zitat von: svenska
Der Kernel startet alle Module, die ihm vorgesetzt wurden. Alle weiteren Services, die nicht boot-kritisch sind, werden später geladen. Was ist daran so schlecht?
Das Problem ist der Bootvorgang an sich. Dort muss eine bestimmte Reihenfolge eingehalten werden um die Sache nicht noch schwieriger zu machen. Als restes muss z.B. der Storage-Server gestartet werden, der bekommt alle Module übergeben und dann wird der Device-Server gestartet, dieser nutzt nur Treiber die schon geladen wurden (dazu muss der Storage-Server aber laufen), sind dann alle Treiber geladen und die entsprechenden Geräte funktionieren, werden weitere Treiber geladen (dafür braucht man wieder die Treiber die der Bootloader mit geladen hat) usw.

Zitat von: svenska
Also wenn ich mir die übliche GRUB-Konfiguration anschaue, dann übergebe ich bei Linux das Kernelbinary und eine initrd/initramfs. Alternativ kannst du ELF-Module laden lassen und er sagt dir sogar, wo er sie hingeladen hat.
Richtig, aber auch unter Linux wird ein Startskript ausgeführt, um aber sowas erstmal machen zu können, müsste ich schon einige Service geladen und gestartet haben und mein Bootskript ist dann ein sehr vereinfachtes Startskript.

Zitat von: svenska
Du brauchst weder TUI noch GUI, solange keine Anwendungen irgendetwas ausgeben möchten. Da du in deinem Konzept IPC benötigst, wenden die Anwendungen (z.B. init) sich an einen well-known-service, der eine Funktionalität bereitstellt. Ist der noch nicht vorhanden, wird er geladen. Schlägt das Fehl, kriegt die Anwendung einen Fehler.
Und genau damit habe ich jetzt ein Problem, wo legst du fest in welcher Datei und an welchem Ort sich dieser well-known-service befindet? Ich möchte halt nicht in irgendeinem Programmcode sagen das der TUI-Server an "/system/tui-server" liegt, sondern möchte das in einem Skript drin haben, wo steht "TUI-SERVER="/system/tui-server"" (oder noch besser UI-SERVER=...), so dass ich ihn auch austauschen könnte.

Vorallem ich möchte einen RPC an den TUI-Server machen also mache ich nen Syscall portGetByName("TUI-SERVER") und dieser gibt mir die Portnummer zurück oder nen Fehler. Was ist nun wenn dieser Server nicht geladen ist, wer soll ihn laden und wer legt fest welche Datei den Server repräsentiert?

Zitat von: svenska
Aber um den Bluetooth-Server registrieren zu können, müsste ich ihn bei dir in den Bootloader eintragen (Fehler: System kaputt) und neu starten. Das meinte ich. Wo das nicht mehr geht, geht das halt nicht mehr.
Das stimmt so nicht. Der Bluetooth-Server ist kein systemkritischer Server und somit ist der mir egal. Was für mich systemkritisch ist, wären Storage, Device, Input und einen Server für die Ausgabe auch der Net-Server wäre jetzt nicht systemkritisch (obwohl man ihn sehr wohl dazu packen könnte, spätestens wenn man über LAN bootet).
Alles was nicht systemkritisch ist und nicht zum Laufen des Systems beiträgt (so dass der User alle anderen Server zur Not per Hand starten kann) sind nicht im Bootskript drin bzw. würde ich die in ein optional-Bootskript auslagern.

Zitat von: svenska
Wenn man sich das IPC als eine Art "Bus" vorstellt, dann hast du einen Service-Server, der diesen Bus abhört und weiß, welche Services gerade existieren. Wenn eine Anfrage nach "SND" kommt, es aber kein "SND" gibt, dann blockiert die Anfrage, bis der Service aktiv ist oder wird mit Fehlercode beantwortet, wenn der Server nicht existiert oder nicht gestartet werden konnte.
Aber woher weiß dieser Service-Server welche Datei den SND-Service repräsentiert?

Ich bin dafür das man, wie unter Windows, die Services die möglich sind, erstmal alle als automatisch starten markiert und der Nutzer kann dann den jeweiligen Service gerne als manuel markieren, so dass dieser nicht mehr automatisch geladen wird, sondern nur noch auf Wunsch des Nutzers.

Zitat von: svenska
Dagegen. Ich würde dlopen() in der libc implementieren und zwar in einer Form, dass der Runtime-Loader selbst diese Funktion benutzen kann, um die Abhängigkeiten aufzulösen. Natürlich muss der Runtime-Loader die Funktion statisch eingelinkt haben (da der Kernel keine dynamischen Dateien ausführen kann).
Sowas in der Art will ich doch machen, aber dlopen() muss ja den Runtime-Loader nutzen, weil ich nicht die Funktionalität um Module (und damit wieder Executeables) parsen zu können nochmal in der libc haben will. Die libc würde nur nen Stub haben, der nen Syscall mit dlopen() macht (so funktioniert das glaub ich unter Linux auch) und dieser Syscall würde den Runtime-Loader in dem aufrufenden Prozess aktivieren und dieser würde dann sein dlopen() (für das entsprechende Format) ausführen.

Problem ist halt nur das der Prozess den Runtime-Loader nicht sehen können soll und d.h. das solange der Runtime-Loader sein dlopen() ausführt muss der komplette Prozess angehalten werden.

Ich denke ich werde für den Anfang einfach ein großes Array nutzen und später wenn alles läuft auf nen Patricia-Tree umsteigen, obwohl ja ELF schon ne Hash-Tabelle für sowas mitbringt, vllt nutze ich auch das.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 29. December 2010, 20:01 »
Das Problem ist der Bootvorgang an sich. Dort muss eine bestimmte Reihenfolge eingehalten werden um die Sache nicht noch schwieriger zu machen.
Da der Bootloader die Module in der Reihenfolge lädt, in der sie in der Datei angegeben sind, sehe ich da kein Problem. Der Rest sind Implementationsdetails. Ich würde die gesamte Komplexität der Serververwaltung aus dem Bootloader herausnehmen (der hat damit nichts zu tun!) und in einen Service-Server stecken. Oder in den Kernel selbst.

Richtig, aber auch unter Linux wird ein Startskript ausgeführt, um aber sowas erstmal machen zu können, müsste ich schon einige Service geladen und gestartet haben und mein Bootskript ist dann ein sehr vereinfachtes Startskript.
Linux führt keinerlei Script aus, bis der Kernel geladen ist, läuft, und ein Userspace funktioniert. Du kannst immernoch ohne initrd booten, das erste Script, was läuft ist dann /sbin/init.

Und genau damit habe ich jetzt ein Problem, wo legst du fest in welcher Datei und an welchem Ort sich dieser well-known-service befindet? Ich möchte halt nicht in irgendeinem Programmcode sagen das der TUI-Server an "/system/tui-server" liegt, sondern möchte das in einem Skript drin haben, wo steht "TUI-SERVER="/system/tui-server"" (oder noch besser UI-SERVER=...), so dass ich ihn auch austauschen könnte.
Andersrum, deine Serverdateien enthalten Header, welche Services sie bereitstellen. Und alle Services liegen in einem well-known-Pfad, Linux-Kernelmodule liegen z.B. immer in /lib/modules/`uname -r`/

Du brauchst an sich kein Script, welches angibt, welcher Service was kann, sondern der Service selbst hat dann einen Header, den du zerpflücken kannst. Das heißt, dein Userland schaut sich alle Service-Dateien an, ermittelt, welche Services existieren (und in welchen Dateien sie auf Platte liegen).

Der TUI-Server stellt dann einen Dienst "TUI" bereit, der GUI-Server (die Diskussion hatten wir schon) stellt z.B. einen Dienst "GUI" und einen Dienst "TUI" bereit. Das heißt, es kann immer nur einer von beiden Diensten aktiv sein.

Vorallem ich möchte einen RPC an den TUI-Server machen also mache ich nen Syscall portGetByName("TUI-SERVER") und dieser gibt mir die Portnummer zurück oder nen Fehler. Was ist nun wenn dieser Server nicht geladen ist, wer soll ihn laden und wer legt fest welche Datei den Server repräsentiert?
Der Syscall könnte feststellen, dass "TUI-SERVER" nicht existiert und blockiert. Dann sucht er in den vorhandenen Dateien nach einem Service, der dieses RPC-/IPC-Target bereitstellt, lädt es, und gibt erst dann die Portnummer zurück oder einen Fehler, wenn es nicht geht.

Das stimmt so nicht. Der Bluetooth-Server ist kein systemkritischer Server und somit ist der mir egal. Was für mich systemkritisch ist, wären Storage, Device, Input und einen Server für die Ausgabe auch der Net-Server wäre jetzt nicht systemkritisch (obwohl man ihn sehr wohl dazu packen könnte, spätestens wenn man über LAN bootet).
Was systemkritisch ist und was nicht, legst nicht du fest. Wer sagt dir eigentlich, dass du nicht über OBEX-Bluetooth booten möchtest? Ich weiß, dass du ausschließlich PC@x86 und PC@x86_64 als Targets betrachtest, aber Input und Output sind auch nicht unbedingt systemkritisch (Systeme ohne Bildschirm & Tastatur).

Die Entscheidung, was im Einzelfall systemkritisch (d.h. zum Booten benötigt) ist, trifft der Benutzer und leitet dieses an den Bootloader weiter.

Alles was nicht systemkritisch ist und nicht zum Laufen des Systems beiträgt (so dass der User alle anderen Server zur Not per Hand starten kann) sind nicht im Bootskript drin bzw. würde ich die in ein optional-Bootskript auslagern.
Ich würde alles, was systemkritisch ist, vom Bootloader anhand dessen Konfiguration laden und alles, was nicht systemkritisch ist, dynamisch vom Userspace ausgehend, wenn es benötigt wird.

Aber woher weiß dieser Service-Server welche Datei den SND-Service repräsentiert?
Weil es in der Datei steht. Mach mal "sudo modinfo rtl8187"...

Ich bin dafür das man, wie unter Windows, die Services die möglich sind, erstmal alle als automatisch starten markiert und der Nutzer kann dann den jeweiligen Service gerne als manuel markieren, so dass dieser nicht mehr automatisch geladen wird, sondern nur noch auf Wunsch des Nutzers.
Pfui.

Sowas in der Art will ich doch machen, aber dlopen() muss ja den Runtime-Loader nutzen, weil ich nicht die Funktionalität um Module (und damit wieder Executeables) parsen zu können nochmal in der libc haben will.
Für mich wäre der Runtime-Loader eine Anwendung wie jede andere auch (nur mit well-known-path und well-known-name und statisch), daher sehe ich kein Problem, wenn dlopen() den Runtime-Loader aufruft. Das muss die libc bei einem exec() ja auch tun, also...

Wenn du aber den Runtime-Loader so sehr tief ins System integrierst, kannst du ihn dafür nicht mehr nutzen.

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 29. December 2010, 20:27 »
Zitat von: svenska
Linux führt keinerlei Script aus, bis der Kernel geladen ist, läuft, und ein Userspace funktioniert. Du kannst immernoch ohne initrd booten, das erste Script, was läuft ist dann /sbin/init.
Und genau um den UserSpace zum Laufen zu bekommen brauche ich Services (das ist ein Problem von einem MikroKernel, erstmal alles zum Laufen zu bekommen) und dafür möchte ich ein Skript nutzen um das möglichst flexibel zu gestalten.

Zitat von: svenska
Du brauchst an sich kein Script, welches angibt, welcher Service was kann, sondern der Service selbst hat dann einen Header, den du zerpflücken kannst. Das heißt, dein Userland schaut sich alle Service-Dateien an, ermittelt, welche Services existieren (und in welchen Dateien sie auf Platte liegen).
Und wie willst du auf die Platte zugreifen um den Storage-Server zu laden und selbst wenn du den schon hast wie willst du ohne Treiber/Device-Server nach einem anderen Server suchen und was machst du wenn du mehrere Dateien findest die die gleichen Services anbieten (das Problem hatten wir beim Treibermanagement schonmal)?

Am liebsten wäre mir ein Skript, wo ich alle wichtigen bzw. alle Server reinpacke die gestartet werden sollen und dieses Skript wird dann abgearbeitet. Dazu bräuchte ich aber nen funktionierenden UserSpace um das Skript von z.B. sh ausführen zu lassen und das wiederum setzt die Server voraus (Henne-Ei-Problem).

Dann gefällt mir bei deinem Ansatz noch nicht, das die Suche nach so einem Service auch mal länger dauern kann. Desweiteren hätte ich Sicherheits Bedenken bei dieser Vorgehensweise, weil wie hindere ich diesen Service-Server daran einen Server zu starten von einem Programm was das eigentlich gar nichts soll (z.B. ist der PC zwar an einem Netzwerk, aber es sollen weder Daten raus noch rein kommen)?

Zitat von: svenska
Was systemkritisch ist und was nicht, legst nicht du fest.
Erstmal richtig, das macht mein Skript ;)

Zitat von: svenska
Wer sagt dir eigentlich, dass du nicht über OBEX-Bluetooth booten möchtest? Ich weiß, dass du ausschließlich PC@x86 und PC@x86_64 als Targets betrachtest, aber Input und Output sind auch nicht unbedingt systemkritisch (Systeme ohne Bildschirm & Tastatur).
Also ich habe durchaus vor mein OS auch auf ARM zu portieren und an x86_64 habe ich noch keine Gedanken verschwendet.
Was das Booten über Bluetooth betrifft, das ist möglich? Sehr interessant und ja sowas will ich eigentlich auch unterstützen, aber deswegen meinte ich ja auch, das man die wichtigsten Server in das Skript packt und alles was sonst noch wichtig ist, wird als Modul geladen und kann dann über den Storage-Server auch ausgeführt werden und wenn ich über Bluetooth booten möchten, dann wird bestimmt der Bluetooth-Server als Modul mitgeladen und wird auch gestartet.

Was Systeme ohne Bildschirm+Tastatur betrifft auch sowas möchte ich unterstützen, aber um mir und den Programmen/Programmierern das Leben nicht schwer zu machen soll alles so laufen als wäre beides vorhanden. Der Input-Server holt sich dann bspw. den Input vom seriellen Port und der TUI-Server leitet den Output zum seriellen Port weiter.
So können alle Programme ganz normal arbeiten und der Bootvorgang läuft auch wie gewöhnt. Bzw. wird der Input-Server einfach den seriellen Port als Stdin weiterleiten und der TUI-Server wird Stdout an den seriellen Port weiterleiten.

Zitat von: svenska
Weil es in der Datei steht. Mach mal "sudo modinfo rtl8187"...
Ich glaube das hatten wir schon, der Linux-Kernel hat ne Liste die zur Compilezeit statisch festlegt welche Module möglich sind und welche nicht (oder?).

Zitat von: svenska
Für mich wäre der Runtime-Loader eine Anwendung wie jede andere auch (nur mit well-known-path und well-known-name und statisch), daher sehe ich kein Problem, wenn dlopen() den Runtime-Loader aufruft. Das muss die libc bei einem exec() ja auch tun, also...
Das verstehe ich jetzt nicht, wie kommt der Runtime-Loader dann an die Symboltabelle ran und wie kann er das Modul in den Prozess integrieren, wenn er als eigenständiger Prozess läuft?

Zitat von: svenska
Wenn du aber den Runtime-Loader so sehr tief ins System integrierst, kannst du ihn dafür nicht mehr nutzen.
Hier verstehe ich jetzt nicht was du meinst. Wofür kann ich den Runtime-Loader dann nicht mehr nutzen?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 29. December 2010, 20:59 »
Und genau um den UserSpace zum Laufen zu bekommen brauche ich Services (das ist ein Problem von einem MikroKernel, erstmal alles zum Laufen zu bekommen) und dafür möchte ich ein Skript nutzen um das möglichst flexibel zu gestalten.
Nimm doch die Konfigurationsdatei des Bootloaders (und nenn diese nicht Script). Was ist das Problem? Die setzt du statisch auf genau die Server, die du brauchst, um Userspace zum Laufen zu bekommen. Fertig.

Und wie willst du auf die Platte zugreifen um den Storage-Server zu laden und selbst wenn du den schon hast wie willst du ohne Treiber/Device-Server nach einem anderen Server suchen und was machst du wenn du mehrere Dateien findest die die gleichen Services anbieten (das Problem hatten wir beim Treibermanagement schonmal)?
Storage-Server, Device-Server, App-Server sind bootkritisch, sind also vom Bootloader bereits geladen worden und laufen. Die ganze dynamische Konfiguration, Zugriffe auf die Platte und so weiter werden vom Userspace getriggert, der muss also per Definition schon da sein.

Dann gefällt mir bei deinem Ansatz noch nicht, das die Suche nach so einem Service auch mal länger dauern kann.
Du erzeugst aus diesen Headern eine Datei, die alle wesentlichen Informationen enthält. Wann immer du Server einträgst oder entfernst, musst du diese Datei aktualisieren. Die Suche nach einem Service dauert dann nur so lange, wie du diese Datei durchsuchen kannst. Das ist akzeptabel.

Desweiteren hätte ich Sicherheits Bedenken bei dieser Vorgehensweise, weil wie hindere ich diesen Service-Server daran einen Server zu starten von einem Programm was das eigentlich gar nichts soll (z.B. ist der PC zwar an einem Netzwerk, aber es sollen weder Daten raus noch rein kommen)?
Das ist ein Implementationsdetail. Das Starten von Services wird von irgendwo koordiniert (schließlich muss der Service identifiziert werden, der passende Server lokalisiert und gestartet). An der Stelle noch ein Flag setzen, dass der Server nicht automatisch gestartet werden soll, ist jetzt nicht mehr soo schwer.

Was das Booten über Bluetooth betrifft, das ist möglich?
Keine Ahnung.

Sehr interessant und ja sowas will ich eigentlich auch unterstützen, aber deswegen meinte ich ja auch, das man die wichtigsten Server in das Skript packt und alles was sonst noch wichtig ist, wird als Modul geladen und kann dann über den Storage-Server auch ausgeführt werden und wenn ich über Bluetooth booten möchten, dann wird bestimmt der Bluetooth-Server als Modul mitgeladen und wird auch gestartet.
Wenn du über OBEXFS oder WLAN booten möchtest, dann brauchst du (theoretisch) nur im Bootloader etwas eintragen:

MODULE /modules/bt/hostadapter-driver
MODULE /modules/bt/btstack-server OBEXFS=geraet,blablub
...
MODULE /modules/storage-server ROOTFS=btstack:geraet:pfad

Da du das Root-Dateisystem ohnehin irgendwo angeben musst, und die Server ihre Services (je nachdem) als Dateisystem angeben können, geht das problemlos. Sehe ich weniger ein Problem, du musst nur irgendwie die Parameter in den Servern verarbeiten können.

Was Systeme ohne Bildschirm+Tastatur betrifft auch sowas möchte ich unterstützen, aber um mir und den Programmen/Programmierern das Leben nicht schwer zu machen soll alles so laufen als wäre beides vorhanden. Der Input-Server holt sich dann bspw. den Input vom seriellen Port und der TUI-Server leitet den Output zum seriellen Port weiter.
Der TUI-Server setzt einfach ein character input und ein character output voraus, und wenn das dein RS232-Server ist, dann ist der das halt. Mach nicht den Fehler und arbeite mit Dummy-Interfaces.

Bedenke, dass die ANSI-Emulation bei RS232 nicht die gleiche ist, wie bei der VGA-Karte.

Zitat von: svenska
Weil es in der Datei steht. Mach mal "sudo modinfo rtl8187"...
Ich glaube das hatten wir schon, der Linux-Kernel hat ne Liste die zur Compilezeit statisch festlegt welche Module möglich sind und welche nicht (oder?).
Nein. Module liegen in /lib/modules/`uname -r`/* und haben einen Header. Jedes Modul hat zur Compilezeit diesen Header verpasst gekriegt und der enthält, welche Geräte von diesem Modul unterstützt werden.

Erweitere das Prinzip und du hast einen Header für Treiber, welche Geräte sie unterstützen und für Server, welche Services sie bereitstellen.

Zitat von: svenska
Für mich wäre der Runtime-Loader eine Anwendung wie jede andere auch (nur mit well-known-path und well-known-name und statisch), daher sehe ich kein Problem, wenn dlopen() den Runtime-Loader aufruft. Das muss die libc bei einem exec() ja auch tun, also...
Das verstehe ich jetzt nicht, wie kommt der Runtime-Loader dann an die Symboltabelle ran und wie kann er das Modul in den Prozess integrieren, wenn er als eigenständiger Prozess läuft?
Hmm, valides Argument. Dazu müsste der Runtime-Loader in die libc integriert sein. Das könnte sogar funktionieren. ;-)

Zitat von: svenska
Wenn du aber den Runtime-Loader so sehr tief ins System integrierst, kannst du ihn dafür nicht mehr nutzen.
Hier verstehe ich jetzt nicht was du meinst. Wofür kann ich den Runtime-Loader dann nicht mehr nutzen?
Entweder, du hast den Runtime-Loader als Kopie ständig im Adressraum jedes Prozesses verfügbar, um dlopen() zu unterstützen, oder du lädst ihn jedesmal neu dort rein. Ich find das nicht soo schön.

;-)

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 29. December 2010, 21:23 »
Zitat von: svenska
Nimm doch die Konfigurationsdatei des Bootloaders (und nenn diese nicht Script). Was ist das Problem? Die setzt du statisch auf genau die Server, die du brauchst, um Userspace zum Laufen zu bekommen. Fertig.
Das sage ich doch die ganze Zeit ;)

Zitat von: svenska
Du erzeugst aus diesen Headern eine Datei, die alle wesentlichen Informationen enthält. Wann immer du Server einträgst oder entfernst, musst du diese Datei aktualisieren. Die Suche nach einem Service dauert dann nur so lange, wie du diese Datei durchsuchen kannst. Das ist akzeptabel.
Das klingt nach einer Art Registry nur in Form von vielen Dateien (Linux typisch und viele bemämgeln das, also die vielen Konfigurationsdateien). Sowas will ich allerdings nicht, weil das würde ja nur funktionieren, wenn mein OS läuft, nur dann könnte diese Datei aktualisiert werden und damit habe ich ein Problem, aber auch das hatten wir schon bei den Treibern.
Allerdings muss ich dir recht geben was die Services betrifft, also mit dem Header, weil sowas will ich ja bei den Treibern nutzen. Ich sehe noch nicht so richtig wie ich das machen sollte, ohne das ich einen Service-Server habe, weil im Kernel würde ich das ungern machen wollen (also Programme laden lassen, zumal das eh schwierig werden dürfte mit meinem Runtime-Loader Konzept).

Zitat von: svenska
An der Stelle noch ein Flag setzen, dass der Server nicht automatisch gestartet werden soll, ist jetzt nicht mehr soo schwer.
Das klingt irgendwie genau nach der Windows Art und Weise, also immer laden lassen, bis es von Hand umgestellt wird ;)

Zitat von: svenska
Da du das Root-Dateisystem ohnehin irgendwo angeben musst, und die Server ihre Services (je nachdem) als Dateisystem angeben können, geht das problemlos. Sehe ich weniger ein Problem, du musst nur irgendwie die Parameter in den Servern verarbeiten können.
Was das betrifft (also das Root-Dateisystem und solche Konzepte), habe ich mir überhaupt noch keinen Kopf gemacht.

Zitat von: svenska
Hmm, valides Argument. Dazu müsste der Runtime-Loader in die libc integriert sein. Das könnte sogar funktionieren.
Genau da sehe ich ein noch größeres Problem (wennd er Runtime-Loader in der libc ist). Denn das hieße ja, das du immer erstmal die libc in einen neuen Prozess packen musst um den Prozess zu erstellen, was ist aber wenn du einen Prozess hast, der keine libc nutzt? Ansonsten ist die Idee gar nicht mal so schlecht. Mal davon abgesehen, das sie sich nicht so viel von meiner unterscheidet, außer das ich den Runtime-Loader noch vor dem bösen bösen Prozess schützen möchte.

Zitat von: svenska
Entweder, du hast den Runtime-Loader als Kopie ständig im Adressraum jedes Prozesses verfügbar, um dlopen() zu unterstützen, oder du lädst ihn jedesmal neu dort rein. Ich find das nicht soo schön.
Er ist in jedem Prozess drin, der Prozess kann ihn nur nicht sehen und wenn du den Runtime-Loader in der libc hättest, wäre er auch in jedem Prozess drin, hätte allerdings den Vorteil das du keinen Syscall machen musst um dlopen() aufzurufen und dafür den Nachteil, das dir das Programme deine Daten zerschießen kann (obwohl das in dem Fall kein Problem sein sollte, bei mir geht es nur darum, das außer dem Runtime-Loader keiner auf bestimmte Syscall Zugriff haben sollen und dazu ist es erforderlich das du den auch nicht kaputt bekommst).

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 29. December 2010, 21:44 »
Das klingt nach einer Art Registry nur in Form von vielen Dateien (Linux typisch und viele bemämgeln das, also die vielen Konfigurationsdateien). Sowas will ich allerdings nicht, weil das würde ja nur funktionieren, wenn mein OS läuft, nur dann könnte diese Datei aktualisiert werden und damit habe ich ein Problem, aber auch das hatten wir schon bei den Treibern.
Du kannst jeden Header durchsuchen, um einen Server zu finden. Das ist bei wenigen Servern eine recht übersichtliche Sache und geht auch recht schnell. Wenn du viele Server hast (wie bei Linux die Module), dann dauert das. Du würdest das Ergebnis der Suche nur Cachen; die Primärquelle bleibt der Header in den Modulen!

Allerdings muss ich dir recht geben was die Services betrifft, also mit dem Header, weil sowas will ich ja bei den Treibern nutzen. Ich sehe noch nicht so richtig wie ich das machen sollte, ohne das ich einen Service-Server habe, weil im Kernel würde ich das ungern machen wollen (also Programme laden lassen, zumal das eh schwierig werden dürfte mit meinem Runtime-Loader Konzept).
Darum versuche ich ja, dir das auszureden. ;-)

Zitat von: svenska
An der Stelle noch ein Flag setzen, dass der Server nicht automatisch gestartet werden soll, ist jetzt nicht mehr soo schwer.
Das klingt irgendwie genau nach der Windows Art und Weise, also immer laden lassen, bis es von Hand umgestellt wird ;)
Du willst sie beim Systemstart laden lassen!

Was das betrifft (also das Root-Dateisystem und solche Konzepte), habe ich mir überhaupt noch keinen Kopf gemacht.
Die Idee mit der Kernel Command Line finde ich extrem genial. ;-)

Genau da sehe ich ein noch größeres Problem (wennd er Runtime-Loader in der libc ist). Denn das hieße ja, das du immer erstmal die libc in einen neuen Prozess packen musst um den Prozess zu erstellen, was ist aber wenn du einen Prozess hast, der keine libc nutzt?
Hmm. Ich bin trotzdem dafür, dass der Runtime-Loader ein eigener, statisch gelinkter Prozess ist, den der Kernel ausführen kann.

In der libc kannst du den Runtime-Loader ja mit fork()/exec() starten, dann bist du im Adressraum des aktuellen Prozesses, also kann der Runtime-Loader ja die Symboltabelle in den Prozess injizieren. Wie man das konkret umsetzt, keine Ahnung.

Er ist in jedem Prozess drin, der Prozess kann ihn nur nicht sehen und wenn du den Runtime-Loader in der libc hättest, wäre er auch in jedem Prozess drin,
Ich würde sowas lieber als externes Hilfsprogramm sehen. Sonst schießt du dir später in den Fuß, weil so gut kannst du den Loader garnicht vor den bösen Programmen schützen.

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 29. December 2010, 22:20 »
Zitat von: svenska
Du kannst jeden Header durchsuchen, um einen Server zu finden. Das ist bei wenigen Servern eine recht übersichtliche Sache und geht auch recht schnell. Wenn du viele Server hast (wie bei Linux die Module), dann dauert das. Du würdest das Ergebnis der Suche nur Cachen; die Primärquelle bleibt der Header in den Modulen!
Naja, das Problem ist weniger die Anzahl der Server, sondern die Anzahl der Dateien in dem Verzeichnis.

Zitat von: svenska
In der libc kannst du den Runtime-Loader ja mit fork()/exec() starten, dann bist du im Adressraum des aktuellen Prozesses, also kann der Runtime-Loader ja die Symboltabelle in den Prozess injizieren. Wie man das konkret umsetzt, keine Ahnung.
Also das mit dem eigenständigen Prozess wird schwierig bis unmöglich. Da kommst du auch mit fork (da änderst du ja nichts im eigentlichen Prozess) und exec (damit löscht du praktisch die Kopie des alten Prozesses) nicht weiter.
Und in der libc ist auch nicht so toll.

Zitat von: svenska
Ich würde sowas lieber als externes Hilfsprogramm sehen. Sonst schießt du dir später in den Fuß, weil so gut kannst du den Loader garnicht vor den bösen Programmen schützen.
Nenne mir mal eine Möglichkeit wie oder wo ich ihn nicht schützen kann. Denn so wie ich mir das vorstelle, hat der Prozess keine Möglichkeit auf die Daten in den ersten 4MB zu zugreifen.

 

Einloggen