Basisfragen zum Paging



  • Hallo zusammen,
    also was Paging ist, ist ja nicht unbedingt schwer zu verstehen. Ich habe halt einen virtuellen Adressraum, der die maximale Größe der Architektur hat (z.B. x86 = 4GB). Dabei ist die virtuelle Adresse ungleich der physischen Adresse. Also ein Zugriff auf die virtuelle Adresse 0x1000 kann ein physischer Zugriff auf die Adresse 0x2000 sein. So weit so gut. Jetzt kommen aber ein Menge Fragen auf.

    1. Nehme wir mal an, dass in unserem System 2 Tasks laufen. Der erste belegt den physischen Adressraum 0-2 MB und der zweite Task den physischen Adressraum 2-4 MB. Die Tasks selber gehen ja aufgrund des virtuellen Speichers davon aus, dass sie beide bei 0 starten und 2 MB lang sind. Der zweite Task weiß ja gar nicht, dass er in Wirklichkeit an der physischen Adresse von 2 MB startet. Jetzt greift Task zwei auf die 1 MB Marke zu. Müsste es nun nicht tierisch krachen, weil die 1 MB Marke ja für Task 1 gemapped ist? Wie unterscheidet man, welchem Task welcher Speicherbereich gehört und wie wird das auch noch richtig übersetzt. Ich meine der Task fordert ja die Adresse an der 1 MB Marke an, aber worher weiß ich nun, ob ich ihm wirklich die 1 MB Marke (1. Task fordert an) oder die 3 MB Marke (2. Task fordert an) geben muss? Ich hoffe es ist halbwegs verständlich, wo mein Verständnisproblem liegt.

    2. Mein Kernel will zum Beispiel wirklich auf die physische Adresse 0xFFFFFF zugreifen, wie kann ich unterscheiden, ob ich jetzt wirklich den Inhalt der physischen Adresse auslesen muss oder aber ob die virtuelle Adresse 0xFFFFFF angesprochen wird. Und wie kann ich bei aktiviertem Paging direkt auf eine physische Adresse zugriefen, nach meine Verständnis sollte dies gar nicht möglich sein oder? Wenn nun eine Paging-Exception geworfen wird, woher soll mein Handler nun wissen, ob die im CR2-Register gespeicherte Adresse eine physische oder virtuelle Adresse ist?

    Ich hatte ursprünglich eigentlich noch ein Frage mehr, aber die ist mir grade entfallen und ich wäre schon sehr glücklich, wenn mir jemand meine obigen beiden Fragen ausführlich bzw. verständlich erklären könnte. Vielleicht fällt mir dann die andere Frage später noch ein.

    Danke schonmal für das Aufklären meiner Fragen 🙂





  • sevobal schrieb:

    1. Nehme wir mal an, dass in unserem System 2 Tasks laufen. Der erste belegt den physischen Adressraum 0-2 MB und der zweite Task den physischen Adressraum 2-4 MB. Die Tasks selber gehen ja aufgrund des virtuellen Speichers davon aus, dass sie beide bei 0 starten und 2 MB lang sind. Der zweite Task weiß ja gar nicht, dass er in Wirklichkeit an der physischen Adresse von 2 MB startet. Jetzt greift Task zwei auf die 1 MB Marke zu. Müsste es nun nicht tierisch krachen, weil die 1 MB Marke ja für Task 1 gemapped ist?

    Wenn task 2 auf die virtuellen 1MB zeigt, also real 3MB, juckt das task 1 doch garnicht, denn dieser kann nur von 0MB bis 2MB sehen. ich sehe kein problem.

    Wie unterscheidet man, welchem Task welcher Speicherbereich gehört und wie wird das auch noch richtig übersetzt. Ich meine der Task fordert ja die Adresse an der 1 MB Marke an, aber worher weiß ich nun, ob ich ihm wirklich die 1 MB Marke (1. Task fordert an) oder die 3 MB Marke (2. Task fordert an) geben muss? Ich hoffe es ist halbwegs verständlich, wo mein Verständnisproblem liegt.

    du setzt eine tabelle die virtuell->real konvertiert. jedesmal wenn ein task auf speicher zugreifen will, wird die addresse dann in der tabelle nachgeschaut (von der hardware), das ist auch mit der grund weshalb du nicht individuelle addressen mappen kannst, sondern nur ganze pages, weil du pro page einen tabelleneintrag haben musst.

    2. Mein Kernel will zum Beispiel wirklich auf die physische Adresse 0xFFFFFF zugreifen, wie kann ich unterscheiden, ob ich jetzt wirklich den Inhalt der physischen Adresse auslesen muss oder aber ob die virtuelle Adresse 0xFFFFFF angesprochen wird. Und wie kann ich bei aktiviertem Paging direkt auf eine physische Adresse zugriefen, nach meine Verständnis sollte dies gar nicht möglich sein oder? Wenn nun eine Paging-Exception geworfen wird, woher soll mein Handler nun wissen, ob die im CR2-Register gespeicherte Adresse eine physische oder virtuelle Adresse ist?

    ein kernel sieht meistens reale addressen und ist auf der untersten sicherheitsebene (ring bzw level), ein task laeuft auf einer eingeschraenktereren ebene und sieht nur fuer den task bereitgestellten speicher.
    fuer den kernel ist der reale speicher das was fuer die einzelnen tasks der virtuelle.

    ansonsten den link zu MMU und http://en.wikipedia.org/wiki/Translation_Lookaside_Buffer folgen 😉


  • Mod



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum Assembler in das Forum Projekt: OS-Development verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Siehe auch die Überarbeitung von Paging und Heap Modul seitens Badestrand:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-254453.html



  • Hallo,

    es ist schade das in diesem Thread gar keine Antwort drin ist! Vor allem weil auf diesen Thread auch noch von hier http://www.c-plusplus.net/forum/viewtopic-var-p-is-1795104.html#1795104 verweisen wird.

    sevobal schrieb:

    1. Nehme wir mal an, dass in unserem System 2 Tasks laufen. Der erste belegt den physischen Adressraum 0-2 MB und der zweite Task den physischen Adressraum 2-4 MB. Die Tasks selber gehen ja aufgrund des virtuellen Speichers davon aus, dass sie beide bei 0 starten und 2 MB lang sind. Der zweite Task weiß ja gar nicht, dass er in Wirklichkeit an der physischen Adresse von 2 MB startet. Jetzt greift Task zwei auf die 1 MB Marke zu. Müsste es nun nicht tierisch krachen, weil die 1 MB Marke ja für Task 1 gemapped ist? Wie unterscheidet man, welchem Task welcher Speicherbereich gehört und wie wird das auch noch richtig übersetzt. Ich meine der Task fordert ja die Adresse an der 1 MB Marke an, aber worher weiß ich nun, ob ich ihm wirklich die 1 MB Marke (1. Task fordert an) oder die 3 MB Marke (2. Task fordert an) geben muss? Ich hoffe es ist halbwegs verständlich, wo mein Verständnisproblem liegt.

    Das Geheimnis ist das jeder Prozess/Task seine eigene Umsetzungstabelle von virtuell nach physisch hat. In beiden Tabellen ist der Bereich von 0 bis 2 MB benutzt. In der Tabelle von Task 1 wird auf die physischen Adressen von 0 bis 2 MB gemappt und in der Tabelle von Task 2 wird dieser Bereich auf die physischen Adressen von 2 bis 4 MB gemappt.

    sevobal schrieb:

    2. Mein Kernel will zum Beispiel wirklich auf die physische Adresse 0xFFFFFF zugreifen, wie kann ich unterscheiden, ob ich jetzt wirklich den Inhalt der physischen Adresse auslesen muss oder aber ob die virtuelle Adresse 0xFFFFFF angesprochen wird. Und wie kann ich bei aktiviertem Paging direkt auf eine physische Adresse zugriefen, nach meine Verständnis sollte dies gar nicht möglich sein oder? Wenn nun eine Paging-Exception geworfen wird, woher soll mein Handler nun wissen, ob die im CR2-Register gespeicherte Adresse eine physische oder virtuelle Adresse ist?

    Auch der Kernel kann nur auf den virtuellen Speicher direkt zugreifen. Wenn er wirklich auf physischen Speicher zugreifen will muss er sich diesen Page für Page in seinen virtuellen Adressraum einblenden und dann damit arbeiten. Da muss der Kernel dann geschickt mit 2 verschiedenen Adressen für den selben Speicher umgehen.

    Ich hab jetzt mal vernachlässigt das der Kernel normalerweise in allen Umsetzungstabellen, immer in der gleichen Weise, mit drin ist.

    Grüße
    Erik


  • Mod

    @erik.vikinger: thx für die Beantwortung. Ich habe dies Badestrand überlassen, da er das Paging-Modul entwickelt hat. Wurde dann aber ganz vergessen. Die Frage hat sich inzwischen sicher auch überholt.



  • Hallo,

    Erhard Henkes schrieb:

    Die Frage hat sich inzwischen sicher auch überholt.

    Gewiss, aber es ist eine sehr wichtige Anfängererkenntnis das man mehrere Umsetzungstabellen braucht und das der Kernel keine eigene hat sondern in allen mit drin ist.

    Erhard Henkes schrieb:

    Ich habe dies Badestrand überlassen,

    Und warum dann das:

    Erhard Henkes schrieb:

    http://www.henkessoft.de/OS_Dev/OS_Dev2.htm#mozTocId554530 Kapitel in meinem OSDEV Tutorial

    Ich konnte dort keine Antwort auf die Originalfragen dieses Threads finden. Auch die präzise Beschreibung der Funktionsweise einer MMU verdeutlicht dem Anfänger nicht wie er diese benutzen muss. Einem Fahranfänger erklärt man doch auch nicht die Funktionsweise eines Autos (jedenfalls nicht detaillierter als unbedingt nötig) sondern die Verkehrsregeln.

    In dem Kapitel "Virtueller Speicher und Swapping" :

    Das sogenannte "swapping" wurde von Microsoft bei Windows 95 bzw. Windows 98 eingeführt und war ein richtiges Lebenselixier für MS Windows.

    Windows 3 konnte bereits swapping und hatte auch einen (optionalen) 32Bit Unterbau auf dem dann alle Win16-Programme per kooperativem Multitasking in einem gemeinsamen Kontext liefen. Außerdem ist swapping bestimmt keine Erfindung von MS, es war bereits zu Windows 3 Zeiten ein alter abgetragener Hut.

    Eigentliche Ursache für diese Technik war die Einführung von Multitasking.

    Ich würde sagen die Ursache für swapping ist die natürliche Knappheit der Ressource RAM.

    In dem Bild in diesem Kapitel könnte man eventuell verdeutlichen das jeder Prozess seine eigene Umsetzungstabelle hat.

    Ich hab mir Deine Seite kurz durchgelesen und bin insgesamt der Meinung das dort viel zu selten erklärt wird warum man bestimmte Dinge tut. Das "Wie" hast Du recht gut und streckenweise sehr erschöpfend abgehandelt aber das "Warum" kommt deutlich zu kurz. Ist aber nur meine persönliche subjektive Meinung.

    Grüße
    Erik


  • Mod

    Danke für das Feedback. Das hast Du richtig erkannt: Paging ist nicht gerade meine Stärke (zumindest beim Schreiben des Tutorials). Ich hoffe, Dir gefällt das neue Modul von Badestrand. 😕



  • Hallo,

    Erhard Henkes schrieb:

    Ich hoffe, Dir gefällt das neue Modul von Badestrand.

    Wo finde ich das?

    Grüße
    Erik


  • Mod


  • Mod

    Hier ist auch noch eine Diskussion zu dem Thema Paging: http://www.c-plusplus.net/forum/viewtopic-var-t-is-254453-and-start-is-20.html



  • Hallo,

    erik.vikinger schrieb:

    Erhard Henkes schrieb:

    Ich hoffe, Dir gefällt das neue Modul von Badestrand.

    Wo finde ich das?

    Ich dachte wir reden über das Tutorial. Euren Source-Code hab ich mir noch gar nicht angesehen.

    Ich hab mir mal die 3 Seiten Deines Tutorials angesehen und muss ganz ehrlich sagen das sich mein erster Eindruck bestätigt hat. Es wird zwar an realem Code gezeigt wie es geht aber es wird quasi kaum eine Designentscheidung näher erläutert. Das Thema "Micro-Kernel vs. Monolith" wird mit ein paar platten Vorurteilen (meine persönliche Meinung) abgehandelt. Dazu könnte auch mal erwähnt werden das ein Monolith einen großen virtuellen Adressraum (z.B. 1GB) benötigt da alle Speicherbereiche der physischen Hardware (Graka-RAM usw.) da hinein gemappt werden müssen wohingegen ein Micro-Kernel mit sehr wenig virtuellem Speicher auskommt (z.B. 64MB) da die physischen Speicherbereiche der Hardware jeweils in den User-Space-Teil der entsprechenden Treiber-Prozesse landen können. Wenn der Leser dessen Hintergründe verstanden hat klappt der Rest bestimmt besser. Das es dann noch prozessspezifische Daten gibt (z.B. die individuellen Paging-Tabellen), die an einer bestimmten Stelle liegen müssen (eventuell sogar im User-Teil) aber für den User trotzdem nicht zugänglich sind, interessiert den Anfänger bestimmt auch.
    Das Thema "Lower-Half-Kernel vs. Upper-Half-Kernel" wird, so wie alle Entscheidungen über den virtuellen Adressraum, gar nicht angegangen.

    Dein Tutorial ist zwar ganz nett aber vermittelt keine allgemeinen Infos sondern ist extrem stark an PrettyOS geknüpft und die Designentscheidungen, die eben zu PrettyOS geführt haben, werden nicht erläutert. Der Leser ist danach zwar in der Lage ein zweites PrettyOS zu schreiben aber die ganzen Designentscheidungen, die für eine Eigenkreation notwendig sind, sind ihm nach wie vor unbekannt.

    Grüße
    Erik



  • Hallo,

    @Erhard Henkes:
    War mein Urteil zu hart? Sorry falls ich zu direkt war.
    Ich bin nicht der Meinung das Dein Tutorial schlecht ist, es fehlen (mir persönlich) nur ein paar wesentliche Aspekte.
    Ich will auch nicht Deine Designentscheidungen als schlecht oder falsch abstempeln, ich finde nur das diese Entscheidungen (von dehnen Du manche vielleicht noch nicht mal bewusst getroffen hast) deutlich sichtbar (und eventuell nachvollziehbar) gemacht werden sollten. In Deinem Tutorial geht es einfach von einer Problemlösung zur nächsten ohne das dem Leser klar wird warum die Probleme gerade so und nicht anders gelöst wurden, was nicht heißen soll das Deine Problemlösungen falsch oder unpassend sind. Ich finde einfach das der "Handlungsstrang" in Deinem Tutorial zu linear ist. Es gibt keine Abzweigungen. Das soll nicht heißen das Du X verschiedene OSe entwickeln sollst sondern nur das diese Abzweigungen im Tutorial deutlich beschrieben werden sollten eventuell mit einer kleinen Begründung warum Du gerade diesen Weg und nicht einen anderen genommen hast. Damit würde Dein Tutorial aus der breiten Masse deutlich positiv herausragen.

    Und der ein oder andere Blick über den Tellerrand ist bei einer so komplexen und vielfältigen Materie wie der OS-Entwicklung einfach Pflicht.

    Auch typische Anfängerfragen, wie jene die diesen Thread gestartet haben, sollten angegangen werden. Uns zweien sind diese Zusammenhänge so selbstverständlich das wir gar nicht mehr darüber nachdenken aber jemand der davon keine Ahnung hat steht vor einem unlösbaren geistigen Knoten. Deswegen fand ich es so unpassend das Du einfach auf Dein Tutorial verweist obwohl dort wirklich gar keine einzige Antwort auf die Fragen vom OP drin sind. Ich persönlich finde Du setzt in Deinem Tutorial zu viel Wissen voraus das ein Anfänger einfach noch nicht hat.

    Wenn Du Dein Tutorial weiter entwickeln möchtest lese ich mir das gerne noch mal durch.

    Grüße
    Erik


  • Mod

    Wenn Du Dein Tutorial weiter entwickeln möchtest lese ich mir das gerne noch mal durch.

    Schau Dir lieber den Sourcecode von Badestrand an und gib dazu deine konstruktive Meinung ab. Das Tutorial ist Geschichte.



  • Hallo,

    Erhard Henkes schrieb:

    Das Tutorial ist Geschichte.

    Warum den das? 😕
    Ich dachte der didaktische Ansatz steht im Vordergrund. Das war eigentlich der einzigste Grund warum ich diesem Projekt hin und wieder ein klein wenig meiner Aufmerksamkeit gewidmet hatte.
    Ein wirklich gutes OS-Dev-Tutorial fehlt im Internet tatsächlich! Normale Hobby-OSe gibt es mehr als man zählen kann!
    In welche Richtung soll es den nun gehen? Wollt Ihr was besonderes in Eurem OS verwirklichen?

    Erhard Henkes schrieb:

    Schau Dir lieber den Sourcecode von Badestrand an und gib dazu deine konstruktive Meinung ab.

    Außer das ich das allozieren von virtuellem und physischen Speicher trennen würde fällt mir nicht viel dazu ein.

    const uint32_t virt_addr = virt_alloc(1**20 , false); //alloziert virtuellen Speicher für den User-Space (bei Fehler kommt 0 zurück)
    alloc_map_phys(virt_addr , 1**20); //alloziert und mappt echten physischen Speicher in diesen virtuellen Speicher (Rückgabewert mit Fehlercode sollte überprüft werden)
    
    /** oder **/
    
    const struct pci_infos; //enthält Infos über ein PCI-Device, mir geht es hier um den Speicher des Gerätes
    const uint32_t virt_addr = virt_alloc(pci_infos.mem_size , true); //alloziert virtuellen Speicher für den Kernel-Space (bei Fehler kommt 0 zurück)
    map_phys(virt_addr , pci_infos.mem_phys_addr , pci_infos.mem_size); //mappt den vorhandenen physischen Speicher in diesen virtuellen Speicher (Rückgabewert mit Fehlercode sollte überprüft werden)
    

    Grüße
    Erik


  • Mod

    Ich dachte der didaktische Ansatz steht im Vordergrund.

    Ja, das stimmt. Aber heute würden wir Badestrands Code verwenden und erläutern. Das kommt alles noch, wie darüber denke ich noch nach. Momentan fehlen einfach die Ressourcen.



  • Hallo,

    Erhard Henkes schrieb:

    Aber heute würden wir Badestrands Code verwenden und erläutern. Das kommt alles noch ...

    Aber dann ist es doch nicht mehr authentisch, nebst dessen das dann wieder die ganzen Designentscheidungen nicht im Tutorial landen. Also ich möchte so ein Tutorial nicht lesen müssen, da kann ich mir auch ne trockene Spec nehmen. Außerdem sollte guter Code selbsterklärend sein.

    Ich kann nur wiederholen :

    erik.vikinger schrieb:

    Ein wirklich gutes OS-Dev-Tutorial fehlt im Internet tatsächlich**!** Normale Hobby-OSe gibt es mehr als man zählen kann**!**

    Grüße
    Erik


  • Mod

    Ein wirklich gutes OS-Dev-Tutorial fehlt im Internet tatsächlich!

    Mein Tutorial ist eher ein Logbook meines eigenen Einstiegs gewesen, also kann es didaktisch noch nicht überlegen sein, also mit allen Möglichkeiten und Gründen für einzelne Wege. Ich habe mich dabei an dem Tutorial von James Molloy orientiert, das leider auch lediglich straight forward geschrieben ist: http://www.jamesmolloy.co.uk/tutorial_html/index.html

    @erik...: wie findest Du eigentlich das neue, sehr ausführliche Tutorial von www.brokenthorn.com? Hier: http://www.brokenthorn.com/Resources/OSDevIndex.html


Anmelden zum Antworten