Autor Thema: Adressraum für Kernel und Prozesse  (Gelesen 25383 mal)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« am: 06. November 2010, 17:40 »
Hallo,

die Frage lautet und ergab sich aus der Diskussion mit FlashBurn an anderer Stelle:

Warum liegt der Kernel üblicherweise im virtuellem Adressraum eines jeden Prozesses?


Meinst du das du den Funktions-Code von einer Kernel-Funktion in den UserSpace mappst und dort dann vom "User" der Code ausgeführt werden kann?
Nicht wirklich... allerdings hab ich keine Ahnung, was ich meine.

Der Prozess fordert einen ausgerichteten Buffer vom Kernel an und merkt sich dessen Zeiger. Dann füllt er diesen mit Daten, setzt die Register (Funktionsnummer, Zeiger auf Buffer, Buffergröße) und ruft dann einen Syscall auf (z.B. "int 80h"). Kann der Kernel dann mit diesem Zeiger etwas anfangen, also den entsprechenden Bereich in seinen eigenen Adressraum mappen und verarbeiten?

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. November 2010, 18:01 »
Zitat von: svenska
Warum liegt der Kernel üblicherweise im virtuellem Adressraum eines jeden Prozesses?
Performance! Und bei einer 64bit Architektur musst du den Kernel auch nicht in einen anderen Adressraum packen, da du ja genug hast.

Zitat von: svenska
Der Prozess fordert einen ausgerichteten Buffer vom Kernel an und merkt sich dessen Zeiger. Dann füllt er diesen mit Daten, setzt die Register (Funktionsnummer, Zeiger auf Buffer, Buffergröße) und ruft dann einen Syscall auf (z.B. "int 80h"). Kann der Kernel dann mit diesem Zeiger etwas anfangen, also den entsprechenden Bereich in seinen eigenen Adressraum mappen und verarbeiten?
Frage wäre was dir das bringen soll, ob du die Daten nun über den Stack oder über einen solchen Buffer (der mehr Speicher verbraucht als wenn man das alles übern Stack macht) an den Kernel weitergibst sollte fast egal sein.

Bzw. die Idee an sich gefällt mir (pro Thread ein 4KB Buffer für Syscalls, aber das wäre halt eigentlich nen tierischer Overhead, denn wieviel Speicher wird man wohl max pro Syscall brauchen, 128Byte?), aber warum willst du diesen Buffer auch im KernelSpace nochmal mappen? Du kannst doch vom KernelSpace aus schon auf den UserSpace zugreifen.

Es gibt ein Bsp. wo das wahrscheinlich sogar so gemacht wird. Wimre dann hat bei MacOSX der Kernel seinen eigenes PageDir und ist somit nicht in jeden Prozess gemappt, sondern da ist immer nur ein kleiner Stub, der das PageDir in den Kernel wechselt.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. November 2010, 18:11 »
Warum liegt der Kernel üblicherweise im virtuellem Adressraum eines jeden Prozesses?
Zum einen, wie FlashBurn schon sagte Performance. Ein Kontextwechsel bedeutet auf x86 einen TLB-Flush und der kostet ein bisschen was.

Zum anderen weil ein paar Teile vom Kernel immer gemappt sein müssen, weil der Prozessor sie benutzt. Die GDT, die IDT und das aktive TSS dürften das absolute Minimum sein, ohne das keinen Wechsel in der Userspace (und vor allem zurück) geht. Und wenn man das sowieso machen muss, ist es am geschicktesten, einfach gleich alles zu mappen.

Außerdem hat es auch noch den Vorteil, dass sich Kernel- und Userspaceadressen nicht überschneiden können und damit zwingend in verschiedenen Adressräumen liegen müssen. Der Kernel muss ja immer mal wieder auf Daten des Userspace zugreifen (z.B. für read, write, send_message, ...) und es wäre umständlich, wenn er dazu jedesmal ein temporäres Mapping anlegen müsste.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 08. November 2010, 10:23 »
Hallo,

das heißt, im Adressraum eines jeden Userspace-Programms müssen mindestens GDT, IDT und TSS vorhanden sein?

Wenn ein Userspace-Prozess einen Syscall aufruft und damit in den Kernel springt, kann der Kernel trotzdem ohne weiteres auf die Userspace-Ressourcen zugreifen? Was, wenn sich die Adressräume überschneiden?

Was muss alles im Kernel-Adressraum liegen, zusätzlich zu Code&Daten, aus denen der Kernel besteht? (Mir fallen da konkret der lineare Grafikspeicher und der PCI-Adressraum ein. Was noch?)

Da fehlt mir irgendwie der Überblick.

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 08. November 2010, 11:35 »
Zitat von: svenska
Wenn ein Userspace-Prozess einen Syscall aufruft und damit in den Kernel springt, kann der Kernel trotzdem ohne weiteres auf die Userspace-Ressourcen zugreifen? Was, wenn sich die Adressräume überschneiden?
Ja, der Kernel kann dann einfach per Pointer (auch wenn man das so einfach nicht machen sollte) auf UserSpace Sachen zugreifen und es kann nicht zu Überschneidungen kommen, da der User 3GB und der Kernel 1GB (z.B. unter Linux), von den vorhanden 4GB Adressraum, bekommt.

Zitat von: svenska
Was muss alles im Kernel-Adressraum liegen, zusätzlich zu Code&Daten, aus denen der Kernel besteht? (Mir fallen da konkret der lineare Grafikspeicher und der PCI-Adressraum ein. Was noch?)
Kommt ganz darauf an von was für einem Kernel wir hier sprechen. Ansonsten reicht alles was man für IPC, VMM, PMM, IRQ und halt Task/Thread-Sachen braucht.
Denn Rest kann man ja im UserSpace machen.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 08. November 2010, 13:23 »
Was passiert, wenn der Kernel nicht im letzten GB des RAMs liegt, sondern die Adressräume sich überschneiden? Geht das dann immernoch so einfach oder muss ich dann per Hand ummappen?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 08. November 2010, 13:34 »
das heißt, im Adressraum eines jeden Userspace-Programms müssen mindestens GDT, IDT und TSS vorhanden sein?
Du brauchst sinnvolles Interrupthandling, und das braucht im Userspace eben diese drei Dinge (IDT um den Interrupthandler nachzuschlagen, GDT um dessen Codesegment zu laden, TSS für den Kernelstack). Ansonsten kommst du nie wieder in den Kernel zurück.

Zitat
Wenn ein Userspace-Prozess einen Syscall aufruft und damit in den Kernel springt, kann der Kernel trotzdem ohne weiteres auf die Userspace-Ressourcen zugreifen?
Spricht nichts dagegen. In der Praxis wird der Kernel natürlich vorher noch prüfen, ob das tatsächlich Daten sind, auf die der Prozess zugreifen können soll.

Zitat
Was, wenn sich die Adressräume überschneiden?
Dann hast du unseren Ratschlag ignoriert, das bleiben zu lassen, und wirst wohl oder übel den Kontext wechseln müssen. ;)

Zitat
Was muss alles im Kernel-Adressraum liegen, zusätzlich zu Code&Daten, aus denen der Kernel besteht? (Mir fallen da konkret der lineare Grafikspeicher und der PCI-Adressraum ein. Was noch?)
Es gibt nicht nur monolithische Kernel...
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 08. November 2010, 16:24 »
Zitat
Was muss alles im Kernel-Adressraum liegen, zusätzlich zu Code&Daten, aus denen der Kernel besteht? (Mir fallen da konkret der lineare Grafikspeicher und der PCI-Adressraum ein. Was noch?)
Es gibt nicht nur monolithische Kernel...
Also nur Code, Daten und IPC-Schnittstelle bei einem Mikrokernel, und was ich schrieb bei einem Monolithen?

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 08. November 2010, 17:05 »
Also was verstehst du darunter das sich die Adressräume überschneiden?

Und was würdest du für Vorteile sehen, wenn der Kernel seinen eigenen 4GB Adressraum hat und nicht in jedem Prozess eingeblendet ist?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 08. November 2010, 22:17 »
Wenn der Kernel im Adressraum von 0 bis 1G liegt und die Anwendungen jeweils von 0 bis 4G-4M liegen, wobei in den letzten 4M die benötigten Strukturen eingeblendet sind, dann überschneiden sich die Adressräume.

Der Vorteil ist, dass du Anwendungen nahezu volle 4 GB virtuellen Speicher zur Verfügung stellen kannst.

Ob das performant und sinnvoll ist, sei mal dahingestellt. Darum die Frage.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 09. November 2010, 10:30 »
Zitat von: svenska
Wenn der Kernel im Adressraum von 0 bis 1G liegt und die Anwendungen jeweils von 0 bis 4G-4M liegen, wobei in den letzten 4M die benötigten Strukturen eingeblendet sind, dann überschneiden sich die Adressräume.
Das geht aber nur, wenn der Kernel sein eigenes PageDir bekommt und dann kannst du ihm auch gleich die vollen 4GB geben.
Ansonsten geht es nicht das Kernel und Anwendungen im gleichen Adressraum sind und sich überschneiden.

Zitat von: svenska
Der Vorteil ist, dass du Anwendungen nahezu volle 4 GB virtuellen Speicher zur Verfügung stellen kannst.
Naja, da wäre halt die Lösung das man irgendwo hin die Strukturen packt die auf jeden Fall benötigt werden und nen Stub wie man in den Kernel wechselt.
Dann ist das möglich und sollte auch nicht alzu schwer sein, nur die Performance wird dann halt nicht so berauschend sein bzw. müsstest du dann dein komplettes Konzept auf SharedMem ausrichten und vorallem sind dann auch Thread-Wechsel sehr "teuer".

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 09. November 2010, 11:10 »
Um Threadwechsel würde ich mir keine Sorgen machen, das passiert jedenfalls im Vergleich selten genug. Aber Syscalls werden ordentlich teuer.

Statt deinem Stub könntest du übrigens auch auf Hardwaremultitasking umsteigen und die CPU das alles machen lassen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 09. November 2010, 11:27 »
Zitat von: taljeth
Statt deinem Stub könntest du übrigens auch auf Hardwaremultitasking umsteigen und die CPU das alles machen lassen.
Du willst also etwas langsames noch langsamer machen ;)

Zumal das nicht wirklich portabel ist.

Zitat von: taljeth
Um Threadwechsel würde ich mir keine Sorgen machen, das passiert jedenfalls im Vergleich selten genug. Aber Syscalls werden ordentlich teuer.
Das "lustige" ist, es würde nur Sinn machen wenn man nen richtigen mikro MikroKernel so implementiert, weil dann wäre jeder Syscall eigentlich eh ne Nachricht zu versenden und dafür musst du eh das PageDir wechseln, also ist das auch nicht so schlimm. Nur braucht ein solcher MikroKernel auch nicht so viel Speicher das es sich lohnen würde ihn in einen extra Adressraum zu packen.

Was die 4GB für die Apps angeht. Ich denke 3GB sollten wirklich reichen und wenn man mehr braucht, 64bit!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 09. November 2010, 11:54 »
Du willst also etwas langsames noch langsamer machen ;)
Hm, weißt du zufällig, was Hardware-MT so langsam macht? Eventuell gerade, dass der TLB jedesmal geflusht wird? Irgendwas muss ja mehr gemacht werden, damit es langsamer wird. Weiß zufällig jemand Bescheid?

Zitat
Zumal das nicht wirklich portabel ist.
Wir reden hier eh über x86 und teilweise x86-spezifische Probleme. Interrupthandling ist nie portabel.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 09. November 2010, 12:04 »
Zitat von: taljeth
Hm, weißt du zufällig, was Hardware-MT so langsam macht?
Wimre, war es "nur" das die Register ja in das TSS kopiert werden. Vorteil vom Software-Multitasking ist das es portabel ist und das du eh schon auf den Stack zugreifst, der also schon mal im TLB/Cache ist und du dann mit nem "pushad" alle Register einfach und schnell gespeichert hast.
Auch hat Intel das Hardware-Tasking dann nicht mehr weiter optimiert, weil es halt kaum bis gar nicht benutzt wurde.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 09. November 2010, 13:48 »
Naja, ob die Register jetzt vom Prozessor ins TSS oder von dir auf den Stack gesichert werden, sollte eigentlich keinen großen Unterschied machen. Was den Cache betrifft, dürfte das ganze sowieso ein, zwei Cache Lines für sich brauchen, und ob die dann für den Stack oder das TSS zuständig sind, macht für mich in meiner naiven Herangehensweise keinen sichtbaren Unterschied.

Und was an für x86 implementiertem Software-Multitasking portabel sein soll, musst du mir erst noch erklären. Diese Teile eines OS sind allgemein architekturabhängig, egal welche Technik man jetzt nimmt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 09. November 2010, 14:04 »
Zitat von: taljeth
Und was an für x86 implementiertem Software-Multitasking portabel sein soll, musst du mir erst noch erklären. Diese Teile eines OS sind allgemein architekturabhängig, egal welche Technik man jetzt nimmt.
Ich behaupte mal alle Architekturen haben nen Stack und wenn du also auf allen Architekturen die Register auf dem Stack sicherst, ist das portabel ;)
Schon alleine das Wort "Software"-Multitasking impleziert doch das es portabel ist, weil es in Software und nicht in Hardware gemacht wird.

An einer anderen Stelle hatten wir mal das Bsp. das irgendein BSD die ganze Verschlüsselung im WLAN per Software macht und so jede WLAN-Hardware WPA2 beherrscht und genauso ist das mit Software-Multitasking. Du kannst das auf jeder Architektur umsetzen auch wenn sie das gar nicht in Hardware (das Multitasking) unterstützt.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 09. November 2010, 14:46 »
Wenn das so plattformunabhängig ist, dann sichere doch mal auf PPC die Register eax, ebx, ecx, edx, esi, edi usw. weg. ;) Allein dass etwas Software ist, macht es noch nicht portabel. Vor allem, wenn es - wie dieser Code - in Assembler geschrieben ist. Oder wir haben grundlegend unterschiedliche Vorstellungen davon, was das Wort "portabel" aussagt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 09. November 2010, 14:56 »
Zitat von: taljeth
Oder wir haben grundlegend unterschiedliche Vorstellungen davon, was das Wort "portabel" aussagt.
An dem Bsp. heißt für mich portabel das ich den Algo genauso wieder umsetzen kann ohne das ich erst irgendwelche Hardware sachen machen muss, sprich das Sichern der Register (welche und wieviele das sind ist ja erstmal egal) auf dem Stack sollte auf jeder Architektur machbar sein. Implementierst du aber Hardware-Multitasking, wirst du andere Strukturen und wahrscheinlich auch nen ganz anderen Algo brauchen.

An diesem Bsp. geht es ja dann weiter, wenn die Register nicht auf dem Stack gesichert sind, musst du an vielen weiteren Stellen auch Code ändern. Obwohl das eigentlich gar nicht nötig wäre.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 09. November 2010, 15:05 »
Du musst sonst nirgends was ändern. Dein Pointer, den du in der Gegend rumreichst, zeigt halt nicht mehr auf den Stack, sondern ins TSS. Das ist alles, was sich ändert.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen