Autor Thema: Treiber bei einem Mikrokernel  (Gelesen 20195 mal)

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« am: 06. September 2010, 13:34 »
Beim Thema IPC Methoden wurde es mal ganz kurz angerissen, das Thema Treiber. Bei einem Mikrokernel ist das Thema nicht so einfach.

Um was es mir aber genau geht, ein Treiber braucht oft (??) die physikalische Adresse einer virtuellen (da DMA kein Paging kennt) und das erste Problem wäre die Sicherheit, ich möchte eigentlich nicht jedem Prozess erlauben rauszubekommen welche physikalische Adresse hinter einer virtuellen steckt.

Aber was wäre das Problem wenn dem so wäre, sprich was könnte ein Prozess damit anfangen?

Ich überlege einfach die Pagingtabellen für Treiber "freizugeben", sprich die können lesend darauf zugreifen (natürlich nur auf den UserSpace-Teil). Was haltet ihr davon? Der Vorteil wäre die Performance, da dadurch Syscalls entfallen würden.

Nächstes Problem wäre, wie bekommt man den Speicher eines Geräts, z.B. den Framebuffer einer Graka, in den Adressraum des Treibers?

Das Problem was ich habe, ist das die ganzen Geräte nicht im Kernel sondern in einem Device-Server verwaltet werden und es so schwieriger wird solchen Speicher zu mappen, weil auch da wieder die Frage ist, wie bekomme ich diesen Speicher in den Device-Server?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. September 2010, 14:09 »
Hallo,

wenn ich als Bösling die physikalische Adresse einer virtuellen Adresse herausbekommen kann, kann ich mittels Buffer-Overflows etc. in den Treibern mittels DMA Codebereiche überschreiben (lassen), die dann später gezielt zur Ausführung gebracht werden. DMA kennt auch keine Sicherheitsmaßnahmen.

Das gesamte Mapping von Speicherbereichen obliegt dem Memory Manager. Das heißt, dein Treiber fordert halt eine gewisse Menge (physikalisch addressierten) Speicher an, die dann in seinen virtuellen Adressraum gemappt wird. Dieser Speicher wird dann zur Kommunikation mit dem Gerät benutzt. Diese Zuordnung ändert sich auch nicht besonders oft, daher solltest du das per Syscall/IPC (an den Memory Manager) machen können.

Zitat
Treiber: "Ich brauche 32 KB ab <phys.adr.>" (Geräte-Konfigregister)
MM:      "Gut, findest du ab <virt.adr.> in deinem Adressraum."
Treiber: "Und ich brauche 64 KB mit 8K-Alignment unterhalb 16 MB" (Geräte-Datenaustausch)
MM:      "Gut, hast du ab <phys.adr.> bei dir im Adressraum ab <virt.adr.>"

Treiber können dann noch eine besondere Privilegierungsstufe bekommen, sodaß normaler Userspace eben nicht den physischen Adressraum benutzen kann. Mit dieser Variante brauchen auch Treiber nicht zwischen physisch und virtuell umrechnen - das erledigt die Speicherverwaltung. Die hat die Daten eh vorliegen und kümmert sich um die Reservierungen.

Gruß

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. September 2010, 14:16 »
Also erstmal das wichtigste: Es heißt physisch, nicht physikalisch. ;)

Ich glaube, was Svenska beschreibt ist das, was tyndur macht. Wenn ein Treiber physischen Speicher einfach irgendwo haben will, dann fordert er vom Kernel Speicher an, setzt aber die Flags passend, damit der Speicher physisch zusammenhängend ist und sowohl virtuelle als auch physische Adresse zurückgegeben werden.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 06. September 2010, 15:21 »
Zitat von: taljeth
Also erstmal das wichtigste: Es heißt physisch, nicht physikalisch.
Wird Zeit das ich wach werde ;)

Mit dem Konzept habe ich so meine Probleme. Wie gehst du sicher das ein Treiber auch nur den Speicher mappt der zu dem Gerät gehört? Ansonsten könnte ein Treiber ja sonstwas für Speicher mappen.
Das nächste ist, ihr geht hier nur von MemoryMapped-IO aus, ich meine aber auch, das du halt einfach sagst, ich (der Treiber) brauche mal 64kb Speicher, brauche die physische Adresse von jeder 4KB Page, damit ich da was reinladen lassen kann.

Auch finde ich es nicht passend das ihr davon ausgeht das der physische Speicher zusammenhängend ist. Erstens kann das mein PMM nicht wirklich und zweitens, was wird gemacht, wenn zwar genug Speicher, aber halt kein zusammenhängender Speicher vorhanden ist?

Zitat von: svenska
wenn ich als Bösling die physikalische Adresse einer virtuellen Adresse herausbekommen kann, kann ich mittels Buffer-Overflows etc. in den Treibern mittels DMA Codebereiche überschreiben (lassen), die dann später gezielt zur Ausführung gebracht werden. DMA kennt auch keine Sicherheitsmaßnahmen.
Sorry, aber das Problem hast du so oder so! Ich meine, man muss schon davon ausgehen, das man einem Treiber vertrauen kann. Denn wie willst du sicher stellen, das ein Treiber die HDD dazu instruiert wirklich nur in den Speicherbereich zu schreiben der dafür vorgesehen ist und nicht irgendwelchen vorhandenen Code überschreibt?

Zitat von: svenska
Treiber können dann noch eine besondere Privilegierungsstufe bekommen, sodaß normaler Userspace eben nicht den physischen Adressraum benutzen kann. Mit dieser Variante brauchen auch Treiber nicht zwischen physisch und virtuell umrechnen - das erledigt die Speicherverwaltung. Die hat die Daten eh vorliegen und kümmert sich um die Reservierungen.
Das habe ich mal gar nicht verstanden ;)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 06. September 2010, 15:46 »
Mit dem Konzept habe ich so meine Probleme. Wie gehst du sicher das ein Treiber auch nur den Speicher mappt der zu dem Gerät gehört? Ansonsten könnte ein Treiber ja sonstwas für Speicher mappen.
Dein Memory Manager hat den Überblick über den gemappten physischen Speicher. Wenn also ein Treiber bereits gemappten physischen Speicher haben will, wird der Request abgelehnt. Außerdem, wenn ich physischen Speicher möchte, ist es mir ja erstmal egal, wo der liegt - die Adresse kann ich dann ja in die Hardware reinprogrammieren.

Du musst dem Treiber schon soweit vertrauen, dass er nicht 2GB physischen Speicher am Stück will. Und wenn doch, kannst du immernoch ablehnen.

Das nächste ist, ihr geht hier nur von MemoryMapped-IO aus, ich meine aber auch, das du halt einfach sagst, ich (der Treiber) brauche mal 64kb Speicher, brauche die physische Adresse von jeder 4KB Page, damit ich da was reinladen lassen kann.
Naja, physischen Speicher brauchst du für zwei Dinge: Datenaustausch mit dem Gerät über DMA und Konfiguration des Gerätes, wenn es über MMIO angebunden ist. Letzteres entfällt natürlich, wenn du über Ports/GPIOs/sonstwas an das Gerät rankommst. Ersteres entfällt, wenn du die Daten irgendwie anders aus dem Gerät rauspopelst (PIO). Dann brauchst du aber auch kein Mapping physisch<->virtuell.

Auch finde ich es nicht passend das ihr davon ausgeht das der physische Speicher zusammenhängend ist. Erstens kann das mein PMM nicht wirklich und zweitens, was wird gemacht, wenn zwar genug Speicher, aber halt kein zusammenhängender Speicher vorhanden ist?
Dann geht das halt nicht, ganz einfach. Wenn mein Gerät DMA machen möchte, muss ich mindestens einen DMA-Block physisch zusammenhängend bereitstellen. Und wenn ich gern "schnell" hätte, muss ich halt mehrere solcher Blöcke haben - im einfachsten Fall als ein großer Block. Ist aber Sache des Treibers, wieviele Blöcke ich welcher Größe wo brauche. In meinem Beispiel sind das einfach 2 Blöcke, die müssen auch nicht hintereinander liegen.

Zitat von: svenska
wenn ich als Bösling die physikalische Adresse einer virtuellen Adresse herausbekommen kann, kann ich mittels Buffer-Overflows etc. in den Treibern mittels DMA Codebereiche überschreiben (lassen), die dann später gezielt zur Ausführung gebracht werden. DMA kennt auch keine Sicherheitsmaßnahmen.
Sorry, aber das Problem hast du so oder so! Ich meine, man muss schon davon ausgehen, das man einem Treiber vertrauen kann. Denn wie willst du sicher stellen, das ein Treiber die HDD dazu instruiert wirklich nur in den Speicherbereich zu schreiben der dafür vorgesehen ist und nicht irgendwelchen vorhandenen Code überschreibt?
Korrekt. Ich dachte, du bezogst dich an der Stelle auf Prozesse allgemein (also nicht nur Treiber). Und du hast ziemlich allgemein gefragt.

Zitat von: svenska
Treiber können dann noch eine besondere Privilegierungsstufe bekommen, sodaß normaler Userspace eben nicht den physischen Adressraum benutzen kann. Mit dieser Variante brauchen auch Treiber nicht zwischen physisch und virtuell umrechnen - das erledigt die Speicherverwaltung. Die hat die Daten eh vorliegen und kümmert sich um die Reservierungen.
Das habe ich mal gar nicht verstanden ;)
Es gibt Anwendungen - es gibt Treiber - und es gibt den Memory Manager. Letzterer darf alles. Treiber dürfen ihren (phys.) Speicher beim Memory Manager beantragen. Anwendungen haben keine Möglichkeit, physische Adressen zu bekommen oder zu ermitteln. Damit können nur Treiber gezielt böse Sachen mit DMA machen, Anwendungen leben ausschließlich im virtuellen Adressraum.

Hoffe, das war verständlicher.

Gruß

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 06. September 2010, 15:46 »
Mit dem Konzept habe ich so meine Probleme. Wie gehst du sicher das ein Treiber auch nur den Speicher mappt der zu dem Gerät gehört?
Kann ich nicht, der Kernel hat keine Ahnung von PCI (oder was auch immer). Klassische Lösung: Alles was als root läuft (oder sonst irgendeine Art von Recht hat), darf das.

Zitat
Das nächste ist, ihr geht hier nur von MemoryMapped-IO aus, ich meine aber auch, das du halt einfach sagst, ich (der Treiber) brauche mal 64kb Speicher, brauche die physische Adresse von jeder 4KB Page, damit ich da was reinladen lassen kann.
Das ist doch genau der Fall, den ich beschrieben habe?

Zitat
Auch finde ich es nicht passend das ihr davon ausgeht das der physische Speicher zusammenhängend ist. Erstens kann das mein PMM nicht wirklich und zweitens, was wird gemacht, wenn zwar genug Speicher, aber halt kein zusammenhängender Speicher vorhanden ist?
Mit virtuell zusammenhängend kann die Hardware aber dummerweise nichts anfangen. Wenn du nicht mehrere Pages physisch zusammenhängend zur Verfügung stellen kannst, musst du dich eben einschränken und maximal 4k auf einmal an die Hardware übergeben.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 06. September 2010, 16:15 »
Zitat von: taljeth
Kann ich nicht, der Kernel hat keine Ahnung von PCI (oder was auch immer). Klassische Lösung: Alles was als root läuft (oder sonst irgendeine Art von Recht hat), darf das.
Und genau das möchte ich bei mir nicht, mit Ports ist das noch relativ einfach und wenn ich eine Möglichkeit gefunden habe, bestimmten Speicher nur in meinem Device-Server zuzulassen, dann habe ich auch das Problem gelöst (ich "vererbe" den Speicher dann einfach an die Treiber, das wäre die Lösung für MemoryMapped-IO).

Zitat von: taljeth
Das ist doch genau der Fall, den ich beschrieben habe?
Nur, will ich das der Speicher nicht unbedingt zusammenhängend sein muss und dann müsste man einen Syscall pro Page machen und das wäre mir halt doch ein wenig zuviel des Guten (würde aber für den Anfang funktionieren) und deswegen dachte ich daran, einfach den Treiber lesend auf die PageTables zugreifen zu lassen.

Zitat von: taljeth
Mit virtuell zusammenhängend kann die Hardware aber dummerweise nichts anfangen. Wenn du nicht mehrere Pages physisch zusammenhängend zur Verfügung stellen kannst, musst du dich eben einschränken und maximal 4k auf einmal an die Hardware übergeben.
Genau so ist das geplant. Die einzige Möglichkeit an zusammenhängenden physischen Speicher zu kommen, ist es 4MB "direkt", also eine 4MB Page, (mein PMM unterstützt das ab 32MB RAM) anzufordern.

Zitat von: svenska
Dein Memory Manager hat den Überblick über den gemappten physischen Speicher.
Was meinst du genau mit "gemappten physischen Speicher"? Meinst du da welcher Speicher in Benutzung ist und welcher nicht?

Das kann mein PMM nicht so richtig. Ich weiß welcher Speicher frei ist, aber mehr auch nicht.

Zitat von: svenska
Außerdem, wenn ich physischen Speicher möchte, ist es mir ja erstmal egal, wo der liegt - die Adresse kann ich dann ja in die Hardware reinprogrammieren.
Wenn wir jetzt über MemoryMapped-IO reden, dann ist es unter Umständen nicht egal wo dieser physische Speicher liegt, bzw. sollte hinter einer MemoryMapped-IO Adresse (im besten Fall, wo also weit weniger als 4GB RAM vorhanden sind) kein physischer Speicher liegen, das Alignment macht dir nämlich einen Strich durch die Rechnung.
Soweit kommt es aber bei mir noch nicht, da ich noch keine Möglichkeiten habe, den Speicher für MemoryMapped-IO selbst zu bestimmen. Dazu müsste ich gezielt Speicher aus meinem PMM entfernen können.

Zitat von: svenska
Dann geht das halt nicht, ganz einfach. Wenn mein Gerät DMA machen möchte, muss ich mindestens einen DMA-Block physisch zusammenhängend bereitstellen. Und wenn ich gern "schnell" hätte, muss ich halt mehrere solcher Blöcke haben - im einfachsten Fall als ein großer Block. Ist aber Sache des Treibers, wieviele Blöcke ich welcher Größe wo brauche. In meinem Beispiel sind das einfach 2 Blöcke, die müssen auch nicht hintereinander liegen.
Das ist aber schlecht! Wie willst du nem User folgendes verklickern:

er hat zwar von seinen 2GB RAM noch 1GB frei, aber da der Speicher so fragmentiert ist dass jede 2. Page (physisch gesehen) in Benutzung ist, kann er keine Daten mehr von seiner HDD laden?

Das ist aber ein ganz schlechtes Konzept. Bevor du mir jetzt mit Paging und Swapping kommst, auch für das Swapping bräuchtest du dann ja mehrere zusammenhängende (physisch) Blöcke.

@svenska

Ich weiß nicht wie dein MemoryManager funktioniert, aber ich habe einen PMM und einen VMM. Der PMM ist einfach nur dafür verantwortlich, das man freien physischen Speicher von ihm bekommt und nicht mehr benötigten physischen (also vorhandener RAM) zurückgeben kann.
Der VMM kümmert sich einfach nur darum, welche virtuelle Adresse frei ist und welche nicht.

Der Punkt ist, mein PMM verwaltet nicht immer 4GB sondern nur soviel Speicher wie da ist.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 06. September 2010, 16:20 »
Nur, will ich das der Speicher nicht unbedingt zusammenhängend sein muss und dann müsste man einen Syscall pro Page machen und das wäre mir halt doch ein wenig zuviel des Guten (würde aber für den Anfang funktionieren) und deswegen dachte ich daran, einfach den Treiber lesend auf die PageTables zugreifen zu lassen.
Den Syscall brauchst du doch sowieso, damit du überhaupt Speicher bekommst, auch wenn er nur virtuell zusammenhängend ist?

Und außerdem würde die PT direkt lesen bedeuten, dass jeder Treiber das Page-Table-Layout kennen muss. Das gibt einen Spaß beim Portieren.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 06. September 2010, 16:43 »
Zitat von: taljeth
Den Syscall brauchst du doch sowieso, damit du überhaupt Speicher bekommst, auch wenn er nur virtuell zusammenhängend ist?
Ja, ich meine aber das:

- Du forderst 64KB an
- bekommst eine virtuelle Adresse zurück
- jetzt machst du für jede 4KB Page einen Syscall um die physische Adresse rauszubekommen

Was man machen könnte, ist einen extra Syscall für Treiber zu implementieren, dem man einen Pointer übergibt, wo man die physischen Adressen des virtuellen Speichers (der angefordert wurde) reinschreibt.

Zitat von: taljeth
Und außerdem würde die PT direkt lesen bedeuten, dass jeder Treiber das Page-Table-Layout kennen muss. Das gibt einen Spaß beim Portieren.
Portabler Code ist nicht wirklich eins meiner Ziele (auch wenn ich es im Hinterkopf habe). Dazu kommt noch, was ist an "getPhysAddr(void *virtAddr)" unportabel? Ich meine, du lagerst das einfach in eine Funktion in einer Bibliothek aus und wie das dann in der Bibliothek implementiert ist, kann dir doch egal sein.

Mein Frage wäre bzw ist noch immer, ob durch das Lesen der PTs wirklich ein Sicherheitsproblem entsteht?

Wie wird der ganze Spaß denn in anderen Mikrokerneln gelöst (rausbekommen welche physische Adresse hinter einer virtuellen steckt)?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 06. September 2010, 17:04 »
Ich überlege einfach die Pagingtabellen für Treiber "freizugeben", sprich die können lesend darauf zugreifen (natürlich nur auf den UserSpace-Teil). Was haltet ihr davon? Der Vorteil wäre die Performance, da dadurch Syscalls entfallen würden.

Zwischen Lesen und Verwenden der physischen Adresse (z.B. Versenden an die HW) vergeht eine gewisse Zeit, in der sich das Mapping ändern kann (Swapping, Copy-on-Write, verzögertes Mapping, MMIO, etc.) Dagegen hilft nur Locking, Pinning, ... wie auch immer man das nennen will. Auf jeden Fall musst du die Zuordnung auf die physischen Adressen in einen definierten Zustand bringen, was dich Syscalls kosten wird.
« Letzte Änderung: 06. September 2010, 17:06 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 06. September 2010, 17:07 »
Zitat von: PorkChicken
Zwischen Lesen und Verwenden der physischen Adresse (z.B. Versenden an die HW) kann eine gewisse Zeit vergehen, in der sich das Mapping ändern kann (Swapping, Copy-on-Write, verzögertes Mapping, MMIO, etc.) Dagegen hilft nur Locking, Pinning, ... wie auch immer man das nennen will. Auf jeden Fall musst du die Zuordnung auf die physischen Adressen in einen definierten Zustand bringen, was dich Syscalls kosten wird.
Würde ich einfach als Flag ("UNSWAPABLE") implementieren, welches dann natürlich nur von Treibern benutzt werden darf, bzw. da ich ohnehin plane solche Buffer dann als SharedMem an andere Prozesse weiterzugeben wäre das Problem auch so gelöst (SharedMem wird bei mir auf keinen Fall ausgelagert).

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 06. September 2010, 17:45 »
Zitat von: taljeth
Kann ich nicht, der Kernel hat keine Ahnung von PCI (oder was auch immer). Klassische Lösung: Alles was als root läuft (oder sonst irgendeine Art von Recht hat), darf das.
Und genau das möchte ich bei mir nicht, mit Ports ist das noch relativ einfach und wenn ich eine Möglichkeit gefunden habe, bestimmten Speicher nur in meinem Device-Server zuzulassen, dann habe ich auch das Problem gelöst (ich "vererbe" den Speicher dann einfach an die Treiber, das wäre die Lösung für MemoryMapped-IO).
Du traust also dem Treiber zu, dass er nicht DMA auf "irgendwelchen" Speicher in die Hardware schreibt, traust ihm dann aber wieder nicht zu, dass er sich Speicher holen darf, den er braucht?

Zitat von: svenska
Dein Memory Manager hat den Überblick über den gemappten physischen Speicher.
Was meinst du genau mit "gemappten physischen Speicher"? Meinst du da welcher Speicher in Benutzung ist und welcher nicht?
Also, die gesamte Speicherverwaltung besteht aus physischem und virtuellem Adressraum, hinter dem jeweils teilweise Speicher steht. Und du musst wissen, welcher Speicher frei ist - getrennt für virtuellen und physischen Speicher, als auch die Verbindung zwischen beiden Adressräumen. Damit weißt du also, welcher Teil des physischen Speichers wo im virtuellen Speicher eines jeden Prozesses gemappt ist.

Zitat von: svenska
Außerdem, wenn ich physischen Speicher möchte, ist es mir ja erstmal egal, wo der liegt - die Adresse kann ich dann ja in die Hardware reinprogrammieren.
Wenn wir jetzt über MemoryMapped-IO reden, dann ist es unter Umständen nicht egal wo dieser physische Speicher liegt, bzw. sollte hinter einer MemoryMapped-IO Adresse (im besten Fall, wo also weit weniger als 4GB RAM vorhanden sind) kein physischer Speicher liegen, das Alignment macht dir nämlich einen Strich durch die Rechnung.
Hä?

Teile des physischen Adressraums sind nicht mit Speicher unterlegt, sondern mit Konfigurationsregistern der Hardware, meist jenseits des realen RAM-Ausbaus (z.B. jenseits der 2GB). Dort muss ein Treiber also unter Umständen physischen Adressraum in seinen eigenen virtuellen Adressraum mappen, der kein RAM ist.
Die Datenkommunikation zwischen Treiber und Hardware läuft dann wiederum über shared memory, wo die physische Adresse bekannt sein muss (wg. DMA). Also musst du auch dort physischen Adressraum, diesmal mit RAM, in den virtuellen Adressraum mappen können.

Wo die Adressen im virtuellen Adressraum landen, ist egal. Welche Adressen im physischen Adressraum benutzt werden, hängt konkret von der Hardware ab (Konfigurationsregister sind fest) und ist nur teilweise programmierbar (Zieladresse des DMA ist es).

Das gilt für MMIO. Wenn du über Ports zugreifst, hast du einen dritten Adressraum, der mit beiden anderen nichts zu tun hat. Für MMIO und DMA muss es auf jeden Fall die beschriebenen Möglichkeiten geben.

Wenn du nur reines PIO machst, brauchst du beides nicht. Welche dieser Möglichkeiten du brauchst, hängt halt konkret von der Hardware ab.

Soweit kommt es aber bei mir noch nicht, da ich noch keine Möglichkeiten habe, den Speicher für MemoryMapped-IO selbst zu bestimmen. Dazu müsste ich gezielt Speicher aus meinem PMM entfernen können.
Als "belegt" markieren reicht aus. Wie gesagt, Teile des physischen Adressraums, den du benötigst, sind nicht mit RAM unterlegt.

Zitat von: svenska
Dann geht das halt nicht, ganz einfach. Wenn mein Gerät DMA machen möchte, muss ich mindestens einen DMA-Block physisch zusammenhängend bereitstellen. Und wenn ich gern "schnell" hätte, muss ich halt mehrere solcher Blöcke haben - im einfachsten Fall als ein großer Block. Ist aber Sache des Treibers, wieviele Blöcke ich welcher Größe wo brauche. In meinem Beispiel sind das einfach 2 Blöcke, die müssen auch nicht hintereinander liegen.
Das ist aber schlecht! Wie willst du nem User folgendes verklickern:

er hat zwar von seinen 2GB RAM noch 1GB frei, aber da der Speicher so fragmentiert ist dass jede 2. Page (physisch gesehen) in Benutzung ist, kann er keine Daten mehr von seiner HDD laden?
Wenn der Treiber physisch 4 MB RAM unterhalb der 16 MB fordert (weil es halt ein popeliger ISA-SCSI-Controller ist), dann wird das wahrscheinlich nicht gehen. Wenn du aber gerne physisch 4 MB RAM als Block irgendwo möchtest, dann geht das wahrscheinlich schon. Ist der RAM voll, dann geht das eben nicht. Wie auch?

Außerdem sollte der Treiber für die Kommunikation mit dem Gerät den Speicher direkt beantragen, oder zumindest einen kleinen Block (z.B. 64 KB). Damit garantierst du auch bei voller Speicherauslastung, dass du die Hardware ansteuern kannst. Alternativ gehst du halt immer weiter runter, bis du einen physischen(!) Block entsprechender Größe bekommst. Dann holst du dir einen Dateisystemblock von der Festplatte halt nur in 4K-Häppchen.

Ich weiß nicht wie dein MemoryManager funktioniert, aber ich habe einen PMM und einen VMM. Der PMM ist einfach nur dafür verantwortlich, das man freien physischen Speicher von ihm bekommt und nicht mehr benötigten physischen (also vorhandener RAM) zurückgeben kann.
Richtig, und was deine Treiber möchten, ist die Möglichkeit, bestimmte und unbestimmte Bereiche zu bekommen.

Der VMM kümmert sich einfach nur darum, welche virtuelle Adresse frei ist und welche nicht.
Was auch hinreicht.

Der Punkt ist, mein PMM verwaltet nicht immer 4GB sondern nur soviel Speicher wie da ist.
Was nicht ausreicht, da der physische Adressraum halt 4GB groß ist und du dort (z.B. ab 3GB) den Framebuffer der Grafikkarte oder die PCI-Konfigurationsregister findest. Die musst du auch verwalten!

Ja, ich meine aber das:

- Du forderst 64KB an
- bekommst eine virtuelle Adresse zurück
- jetzt machst du für jede 4KB Page einen Syscall um die physische Adresse rauszubekommen

Was man machen könnte, ist einen extra Syscall für Treiber zu implementieren, dem man einen Pointer übergibt, wo man die physischen Adressen des virtuellen Speichers (der angefordert wurde) reinschreibt.
Warum so kompliziert? Was hat dein Treiber davon, wenn er sich jede einzelne Page, die er für die Kommunikation mit der Hardware braucht, einzeln anfordern muss? Außerdem garantierst du ja nicht, dass die Pages zusammenhängend sind.

Erklär du mal dem HDD-Controller, dass er die ersten 4 KB nach 0x3400 0000, die zweiten 4 KB nach 0x3800 0000 und die dritten 4 KB nach 0x3400 8000 schreiben soll. Das heißt, du programmierst die Hardware dreimal, um 12KB von der Festplatte zu lesen.

Implementier lieber zwei Funktionen:

*getPhysMem( int size, ptr physAddr )
-> gib mir "size" Bytes ab physisch "physAddr" zurück
=> malloc() mit gegebener Adresse für deinen PMM

*getPhysMem( int size, ptr *physAddr )
-> gib mir "size" Bytes Speicher und schreibe in "physAddr" die physische Adresse rein
=> malloc() mit Rückgabe der verwendeten physischen Adresse

Wenn du willst, kannst du noch einen Alignment-Parameter mit einbinden, wenn du z.B. Hardware hast, die ein Alignment >4K braucht.

Was du dir sparst:
- Prozesse müssen die PageTables nicht selbst parsen können (Portabilität, vgl. taljeth)
- Prozesse haben keine Möglichkeit, das Mapping zwischen virt. und phys. Adressraum rauszukriegen (Sicherheit)
- nur ein Syscall pro Treiber und Adressraumblock

Oder sage mir, warum mein Ansatz nicht geht.

Gruß

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 06. September 2010, 18:40 »
Zitat von: svenska
Du traust also dem Treiber zu, dass er nicht DMA auf "irgendwelchen" Speicher in die Hardware schreibt, traust ihm dann aber wieder nicht zu, dass er sich Speicher holen darf, den er braucht?
Naja, wenn du so ran gehst, dann brauchst du für einen Treiber gar keine Sicherheit! Wozu kontrollieren auf welche Ports der Treiber zugreifen darf?
Ich will, soweit es geht, ein wenig Sicherheit auch vor Treibern. Das ich mich nicht vor falschen DMA Adressen schützen kann, ist leider schade, aber damit muss ich leben.
Da ist der alte ISA DMA Kontroller natürlich besser zu kontrollieren. Denn den könntest du noch abstrahieren und selbst kontrollieren und die Treiber müssten dann alle DMA Anforderungen an dich (als z.B. Server) machen.

Zitat von: svenska
Damit weißt du also, welcher Teil des physischen Speichers wo im virtuellen Speicher eines jeden Prozesses gemappt ist.
Mein Problem hier ist, meinst du damit auch, dass ich wissen müsste in welchem Prozess die Page 0x1000 ist? Denn das könnte ich zwar rausbekommen, aber nur ziemlich umständlich indem ich von jedem Prozess die PTs einblenden müssten (in den Kernel) und die PTs dann nach der Page durchsuchen müsste. Bis das alles fertig ist, kann die Page schonwieder in einem ganz anderem Prozess sein (zwecks Swapping).

Zitat von: svenska
Teile des physischen Adressraums sind nicht mit Speicher unterlegt, sondern mit Konfigurationsregistern der Hardware, meist jenseits des realen RAM-Ausbaus (z.B. jenseits der 2GB). Dort muss ein Treiber also unter Umständen physischen Adressraum in seinen eigenen virtuellen Adressraum mappen, der kein RAM ist.
Was du meinst ist linearer Adressraum und virtueller Adressraum! Physischer Speicher (wie der Name schon sagt) ist wirklich vorhandener RAM!
Und wenn du auf einem 32bit System 4GB RAM hast, dann belegt auch MMIO physischen RAM, was halt weniger schön, aber unvermeidbar ist.

Zitat von: svenska
Wo die Adressen im virtuellen Adressraum landen, ist egal. Welche Adressen im physischen Adressraum benutzt werden, hängt konkret von der Hardware ab (Konfigurationsregister sind fest) und ist nur teilweise programmierbar (Zieladresse des DMA ist es).
Da liegst du falsch. Denn die MMIO Adressen von PCI Geräten kann man sehr wohl selber bestimmen oder wie meinst du funktioniert das!? Eigentlich macht das BIOS diese Verwaltung, aber wenn es das nicht macht, müsstest du es selber machen und genau das ist momentan bei mir nicht möglich (da ich noch nichts habe, um bestimmte Pages im PMM als benutzt zu markieren).

Zitat von: svenska
Wie gesagt, Teile des physischen Adressraums, den du benötigst, sind nicht mit RAM unterlegt.
Wie oben geschrieben, stimmt das leider nicht immer.

Zitat von: svenska
Wenn der Treiber physisch 4 MB RAM unterhalb der 16 MB fordert (weil es halt ein popeliger ISA-SCSI-Controller ist), dann wird das wahrscheinlich nicht gehen. Wenn du aber gerne physisch 4 MB RAM als Block irgendwo möchtest, dann geht das wahrscheinlich schon. Ist der RAM voll, dann geht das eben nicht. Wie auch?
Deswegen macht es z.B. Linux auch so, dass so lange wie freier Speicher >16MB vorhanden ist, wird dieser genommen und somit kann der Speicher <16MB für ISA Treiber genutzt werden. Bei meinem Bsp darf das also nicht passieren.
Mir geht es auch nicht darum das der RAM voll ist, sondern das er fragmentiert ist!

Zitat von: svenska
Außerdem sollte der Treiber für die Kommunikation mit dem Gerät den Speicher direkt beantragen, oder zumindest einen kleinen Block (z.B. 64 KB). Damit garantierst du auch bei voller Speicherauslastung, dass du die Hardware ansteuern kannst.
Ich habe mir das für ISA Geräte so vorgestellt, das sie immer "nur" 64KB Speicher bekommen (davon wird es 8-10 Blöcke geben) und mit diesem Block dann auch auskommen müssen.

Aber die Idee kann ich auch auf andere Treiber übertragen. Problematisch wären dann aber Systeme mit wenig RAM (im Moment soll mein OS auch mit 8MB klar kommen), wo man nicht einfach mal sagenkann , ich benutze jetzt immer 4MB um die Daten von HDD in den Speicher zu bekommen und kopiere die Daten dann in SharedMem.
Was man machen könnte, ist je nach Speicherausstattung einen Cache bei der Initialisierung anzulegen.

Zitat von: svenska
Was nicht ausreicht, da der physische Adressraum halt 4GB groß ist und du dort (z.B. ab 3GB) den Framebuffer der Grafikkarte oder die PCI-Konfigurationsregister findest. Die musst du auch verwalten!
Im Moment gehe ich noch davon aus, dass das BIOS diese Arbeit für mich schon gemacht hat, aber ich werde mir wohl nochmal was einfallen lassen müssen wie ich es mache, wenn das nicht der Fall ist. Wobei hier dann auch die Frage aufkommt, wie bekomme ich raus, dass das BIOS die Arbeit schon gemacht hat?

Zitat von: svenska
Was hat dein Treiber davon, wenn er sich jede einzelne Page, die er für die Kommunikation mit der Hardware braucht, einzeln anfordern muss? Außerdem garantierst du ja nicht, dass die Pages zusammenhängend sind.
Der Treiber fordert ja nicht jede Page einzeln an, sondern er muss für jede Page einzeln nachgucken welche physische Adresse dahinter steckt und das genau wegen dem Grund, dass die Pages nicht zusammenhängend sein müssen (es bei der Initialisierung aber höchst wahrscheinlich sein werden).

Zitat von: svenska
Erklär du mal dem HDD-Controller, dass er die ersten 4 KB nach 0x3400 0000, die zweiten 4 KB nach 0x3800 0000 und die dritten 4 KB nach 0x3400 8000 schreiben soll. Das heißt, du programmierst die Hardware dreimal, um 12KB von der Festplatte zu lesen.
Im schlimmsten Fall, ja ;) Aber bevor es soweit kommt, würde ich halt sagen, der Treiber guckt wieviel RAM das System gesamt hat und legt sich danach einen Cache an (für DMA) und damit ist das Problem dann auch gegessen. Obwohl es gerade bei der HDD nicht die Welt sein sollte, für jede Page eine neue Anfrage zu machen, da ersten die Datei sowieso fragmentiert sein könnte (dann musst du das eh machen) und die Festplatte so "langsam" liest das sich an der absoluten Zeit nicht viel ändern wird.

Zitat von: svenska
Implementier lieber zwei Funktionen:

*getPhysMem( int size, ptr physAddr )
-> gib mir "size" Bytes ab physisch "physAddr" zurück
=> malloc() mit gegebener Adresse für deinen PMM

*getPhysMem( int size, ptr *physAddr )
-> gib mir "size" Bytes Speicher und schreibe in "physAddr" die physische Adresse rein
=> malloc() mit Rückgabe der verwendeten physischen Adresse
Also beide Funktionen haben schonmal das Problem (was aber auch nur meiner Sichtweise entspricht) das sie mit "Bytes" arbeiten, aber die Größe eigentlich auf 4KB Blöcke beschränkt ist.
Dann habe ich bei der ersten Funktion noch das Problem, versuche das mal bei einem PMM der mit nem Stack arbeitet!
Die 2. Funktion ist da schon eher was für mich, aber siehe weiter unten.

Zitat von: svenska
Wenn du willst, kannst du noch einen Alignment-Parameter mit einbinden, wenn du z.B. Hardware hast, die ein Alignment >4K braucht.
Gibt es sowas (also wo die Adresse wo das Gerät hinschreiben soll ein Alignment >4K brauch)? Das wäre ein echtes Problem :(

Zitat von: svenska
Was du dir sparst:
- Prozesse müssen die PageTables nicht selbst parsen können (Portabilität, vgl. taljeth)
- Prozesse haben keine Möglichkeit, das Mapping zwischen virt. und phys. Adressraum rauszukriegen (Sicherheit)
- nur ein Syscall pro Treiber und Adressraumblock
Was die Portabilität betrifft, siehe meine Antwort darauf und auch muss es der Treiber nicht selbst könne (siehe selbe Antwort).
Mir hat noch keiner eine wirkliche Antwort gegeben wo das Sicherheitsproblem wäre, wenn der Treiber die PTs parsen könnte.
Beim Parsen der PTs hätte ich auch nur einen Syscall.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 06. September 2010, 19:34 »
Zitat von: svenska
Du traust also dem Treiber zu, dass er nicht DMA auf "irgendwelchen" Speicher in die Hardware schreibt, traust ihm dann aber wieder nicht zu, dass er sich Speicher holen darf, den er braucht?
Naja, wenn du so ran gehst, dann brauchst du für einen Treiber gar keine Sicherheit! Wozu kontrollieren auf welche Ports der Treiber zugreifen darf?
Darum würde ich das auch komplett weglassen. Wichtig ist nur, dass keine Ressource von zwei Treibern angefordert wird, weil dann ist etwas faul. Wenn somit jede Hardware ihren Treiber hat, kann kein neuer Treiber mehr Unfug machen. Nicht elegant, aber besser als garnichts.

Mein Problem hier ist, meinst du damit auch, dass ich wissen müsste in welchem Prozess die Page 0x1000 ist? Denn das könnte ich zwar rausbekommen, aber nur ziemlich umständlich indem ich von jedem Prozess die PTs einblenden müssten (in den Kernel) und die PTs dann nach der Page durchsuchen müsste. Bis das alles fertig ist, kann die Page schonwieder in einem ganz anderem Prozess sein (zwecks Swapping).

Ich sehe den physischen Adressraum an dieser Stelle so, wie er auf dem Adressbus rausgeführt wird (wie die Hardware die Speicheradresse sieht) und den virtuellen Adressraum, wie ihn die Anwendung sieht. Welcher Treiber nun diesen physischen Speicherblock angefordert hat, dürfte dir relativ egal sein - da kümmert sich ja der Treiber selbst drum. Also bräuchtest du das nicht raussuchen.

Zitat von: svenska
Teile des physischen Adressraums sind nicht mit Speicher unterlegt, sondern mit Konfigurationsregistern der Hardware, meist jenseits des realen RAM-Ausbaus (z.B. jenseits der 2GB). Dort muss ein Treiber also unter Umständen physischen Adressraum in seinen eigenen virtuellen Adressraum mappen, der kein RAM ist.
Was du meinst ist linearer Adressraum und virtueller Adressraum! Physischer Speicher (wie der Name schon sagt) ist wirklich vorhandener RAM!
Und wenn du auf einem 32bit System 4GB RAM hast, dann belegt auch MMIO physischen RAM, was halt weniger schön, aber unvermeidbar ist.
Oh, das ist dann mein Fehler. Darum habe ich ja auch physischen Speicher (z.B. 2GB) von physischem Adressraum (immer 4GB) getrennt.

Zitat von: svenska
Wo die Adressen im virtuellen Adressraum landen, ist egal. Welche Adressen im physischen Adressraum benutzt werden, hängt konkret von der Hardware ab (Konfigurationsregister sind fest) und ist nur teilweise programmierbar (Zieladresse des DMA ist es).
Da liegst du falsch. Denn die MMIO Adressen von PCI Geräten kann man sehr wohl selber bestimmen oder wie meinst du funktioniert das!? Eigentlich macht das BIOS diese Verwaltung, aber wenn es das nicht macht, müsstest du es selber machen und genau das ist momentan bei mir nicht möglich (da ich noch nichts habe, um bestimmte Pages im PMM als benutzt zu markieren).

Also ist die Hardwareseite:
- das Gerät hat fixe Register bei 0xFFF08000-0xFFF0FFFF (findest du eher nicht auf dem PC)
- das Gerät hat konfigurierbare Register, die vom BIOS irgendwo hingelegt wurden, für dich also fix sind
- das Gerät hat konfigurierbare Register, deren Ort im linearen Adressraum du frei festlegen kannst
Was davon jetzt auf PCI zutrifft und was nicht, weiß ich nicht. Auf meinem ARM funktioniert der Framebuffer nach letzterem Prinzip. (Ich habe zwei Register bei 0x4D00 0014 und 0x4D00 0018, die die Position des Framebuffers im linearen Adressraum enthalten.)

Dein Treiber muss jetzt auf diese Register zugreifen können, also wird dieser Speicherbereich in den virtuellen Adressraum des Prozesses gemappt. Die virtuelle Adresse ist dabei egal. Konkret hast du deine virtuelle Adresse, die auf eine bekannte physische Speicheradresse zeigt. Und genau dieses Mapping muss deine Speicherverwaltung kennen. Welcher Prozess jetzt eine bestimmte physische Speicherseite hat, kann dir dabei egal sein.

Zitat von: svenska
Wie gesagt, Teile des physischen Adressraums, den du benötigst, sind nicht mit RAM unterlegt.
Wie oben geschrieben, stimmt das leider nicht immer.
Ich gehe von unter 4GB RAM auf einer 32-Bit-Maschine aus. Für den Fall, dass du 4GB RAM hast, wird er beim Lesen und Schreiben ohnehin ignoriert und ist nicht nutzbar. Bei aktivem PAE hast du wieder mehrere 4GB-Adressräume...

Mir geht es auch nicht darum das der RAM voll ist, sondern das er fragmentiert ist!
Wenn dein RAM physisch fragmentiert ist, hast du halt Pech. Darum legst du im Treiber ja auch bei der Initialisierung bereits deine Speicherblöcke an! Außerdem brauchst du für viele Geräte den Datenaustausch schon, um die Geräte initialisieren zu können.

Aber die Idee kann ich auch auf andere Treiber übertragen. Problematisch wären dann aber Systeme mit wenig RAM (im Moment soll mein OS auch mit 8MB klar kommen), wo man nicht einfach mal sagenkann , ich benutze jetzt immer 4MB um die Daten von HDD in den Speicher zu bekommen und kopiere die Daten dann in SharedMem.
Was man machen könnte, ist je nach Speicherausstattung einen Cache bei der Initialisierung anzulegen.
Wichtig ist, wie groß die Datenblöcke sind, die du bekommst und wieviel ein einzelner DMA-Transfer machen kann oder im Normalfall macht. Selbst bei 8MB RAM hast du 64K für die Festplatte übrig, wahrscheinlich sogar 512 KB. Das kannst du einmal in Abhängigkeit des RAMs ausrechnen lassen (64K bei <32MB, 1M bei <64MB und 4M sonst), außerdem kannst du das auch dynamisch anpassen - solange du einen physisch hinreichend großen freien Block hast. Das erledigst du dann aber im Treiber.

Zitat von: svenska
Was nicht ausreicht, da der physische Adressraum halt 4GB groß ist und du dort (z.B. ab 3GB) den Framebuffer der Grafikkarte oder die PCI-Konfigurationsregister findest. Die musst du auch verwalten!
Im Moment gehe ich noch davon aus, dass das BIOS diese Arbeit für mich schon gemacht hat, aber ich werde mir wohl nochmal was einfallen lassen müssen wie ich es mache, wenn das nicht der Fall ist. Wobei hier dann auch die Frage aufkommt, wie bekomme ich raus, dass das BIOS die Arbeit schon gemacht hat?
Ich kann mir irgendwie nicht vorstellen, dass dir das BIOS jeglichen Speicher, den eine Hardware benutzen mag, schon vorgekaut als Liste gibt... die Arbeit, sich die Adressräume einzuteilen, obliegt doch eigentlich dem Betriebssystem.

Zitat von: svenska
Was hat dein Treiber davon, wenn er sich jede einzelne Page, die er für die Kommunikation mit der Hardware braucht, einzeln anfordern muss? Außerdem garantierst du ja nicht, dass die Pages zusammenhängend sind.
Der Treiber fordert ja nicht jede Page einzeln an, sondern er muss für jede Page einzeln nachgucken welche physische Adresse dahinter steckt und das genau wegen dem Grund, dass die Pages nicht zusammenhängend sein müssen (es bei der Initialisierung aber höchst wahrscheinlich sein werden).
Dann gib eine Garantie vor. Macht die Treiberentwicklung wesentlich einfacher. Für Hardware willst du "RAM am Stück", alles andere ist sinnlos, von Scatter-Gather-Zugriffsmodi mal abgesehen, aber die haben andere Gründe.

Zitat von: svenska
Erklär du mal dem HDD-Controller, dass er die ersten 4 KB nach 0x3400 0000, die zweiten 4 KB nach 0x3800 0000 und die dritten 4 KB nach 0x3400 8000 schreiben soll. Das heißt, du programmierst die Hardware dreimal, um 12KB von der Festplatte zu lesen.
Im schlimmsten Fall, ja ;) Aber bevor es soweit kommt, würde ich halt sagen, der Treiber guckt wieviel RAM das System gesamt hat und legt sich danach einen Cache an (für DMA) und damit ist das Problem dann auch gegessen. Obwohl es gerade bei der HDD nicht die Welt sein sollte, für jede Page eine neue Anfrage zu machen, da ersten die Datei sowieso fragmentiert sein könnte (dann musst du das eh machen) und die Festplatte so "langsam" liest das sich an der absoluten Zeit nicht viel ändern wird.
Warum sollte der HDD-Treiber den gleichen RAM zweimal verbrauchen, nur weil du ihm keinen Block garantieren wolltest? In dem Moment hast du einen Cache am Stück und die Daten tauchen dann in 25 verschiedenen Speicherseiten auf und werden dorthin zusammengepopelt, ehe die Daten an deine Anwendung übergeben werden.

Zitat von: svenska
Implementier lieber zwei Funktionen:

*getPhysMem( int size, ptr physAddr )
-> gib mir "size" Bytes ab physisch "physAddr" zurück
=> malloc() mit gegebener Adresse für deinen PMM

*getPhysMem( int size, ptr *physAddr )
-> gib mir "size" Bytes Speicher und schreibe in "physAddr" die physische Adresse rein
=> malloc() mit Rückgabe der verwendeten physischen Adresse
Also beide Funktionen haben schonmal das Problem (was aber auch nur meiner Sichtweise entspricht) das sie mit "Bytes" arbeiten, aber die Größe eigentlich auf 4KB Blöcke beschränkt ist.
Spielt keine Rolle, dann rundest du eben auf die nächsten 4K auf. Du könntest ja auch Paging mit anderen Größen machen (z.B. 2K)

Dann habe ich bei der ersten Funktion noch das Problem, versuche das mal bei einem PMM der mit nem Stack arbeitet!
Das ist ein Program der Implementierung. Diese beiden Funktionen machen aber die Treiberentwicklung wesentlich einfacher.

Zitat von: svenska
Wenn du willst, kannst du noch einen Alignment-Parameter mit einbinden, wenn du z.B. Hardware hast, die ein Alignment >4K braucht.
Gibt es sowas (also wo die Adresse wo das Gerät hinschreiben soll ein Alignment >4K brauch)? Das wäre ein echtes Problem :(
Ich würde es nicht kategorisch ausschließen wollen. Im Härtefall hat der Gerätehersteller das Datenblatt des Chipherstellers falsch gelesen und eine Leitung zuwenig angeschlossen. Silicon Bugs sind manchmal echt tolle Dinger.

Mir hat noch keiner eine wirkliche Antwort gegeben wo das Sicherheitsproblem wäre, wenn der Treiber die PTs parsen könnte.
Beim Parsen der PTs hätte ich auch nur einen Syscall.
Was der Treiber nicht braucht, würde ich ihm auch nicht erzählen. Wenn der Treiber keine physischen/linearen Adressen kennt, die er nicht selbst für seine Arbeit braucht, dann kann er auch nicht versehentlich Schaden anrichten. Und da in meinem Ansatz der Treiber die physischen Adressen zugeteilt kriegt (es sei denn, er fordert sie selbst an - dann kennt er sie aber vorher schon und sie werden noch nicht benutzt)... der Netzwerktreiber muss nicht wissen, wo der HDD-Treiber die Sektoren hinspeichert. Was man mit dem Wissen machen kann, hatte ich oben schon geschrieben. Ist halt ne grundsätzliche Sache.

Gruß

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 06. September 2010, 19:55 »
Zitat von: svenska
Darum würde ich das auch komplett weglassen. Wichtig ist nur, dass keine Ressource von zwei  Treibern angefordert wird, weil dann ist etwas faul. Wenn somit jede Hardware ihren Treiber hat, kann kein neuer Treiber mehr Unfug machen. Nicht elegant, aber besser als garnichts.
Also entweder ganz oder gar nicht ;)

Wenn ich schon kontrolliere das solch Speicher nicht zweimal vergeben wird, dann kann ich auch kontrollieren (weil ich eh einmal dabei bin) an wenn er gegeben wird. Das selbe mach ich ja schon bei den IO-Ports.

Was ich eigentlich erreichen möchte ist, dass der Treiber ansich nur ein paar IO-Ports oder einen SharedMem-Bereich bekommt und ansonsten eigentlich gar nicht weiß wo das alles liegt.
Sprich am besten wäre es wenn der Treiber einfach immer bei Port 0 anfangen würde und man das ganze dann per Exception abfängt und den Port 0 auf den ersten Port des Gerätes "umleitet". Da dass aber zu kostspielig ist, mach ich es über die IO-Bitmap.
Was ich aber auf jeden Fall haben möchte ist, das nicht der Treiber entscheidet welche Ressourcen er gerne haben möchte, sondern das ich (Kernel oder Server, ist ansich egal) ihm sage, so die Ressourcen sind deine und an andere kommst du nicht ran.

Zitat von: svenska
Was davon jetzt auf PCI zutrifft und was nicht, weiß ich nicht.
Also soweit ich die PCI Specs verstanden (und gelesen) habe, sind weder die Adressen von MMIO (wo ich auch nen Framebuffer dazu zähle) noch die IO-Ports fixed, sondern können festgelegt werden (aber man muss sich an bestimmte Alignments halten).

Zitat von: svenska
Wenn dein RAM physisch fragmentiert ist, hast du halt Pech.
Sorry, aber mit der Einstellung kommst du nicht weit und genau dafür wurde ja Paging "erfunden", nur dass das bei DMA nicht funktioniert (bzw. kann ich mich erinnern, das es Geräte gibt wo du auch immer 4KB Blöcke reinschreibst und das Geräte dann die Daten da hinkopiert, so wird das Problem umgangen).

Zitat von: svenska
Ich kann mir irgendwie nicht vorstellen, dass dir das BIOS jeglichen Speicher, den eine Hardware benutzen mag, schon vorgekaut als Liste gibt... die Arbeit, sich die Adressräume einzuteilen, obliegt doch eigentlich dem Betriebssystem.
Da hast du mich falsch verstanden. Das BIOS legt die MMIOs und Framebuffers möglichst perfekt an das Ende des linearen Adressraumes. Ansonsten müsstest du alle PCI Geräte enumieren und anhand von ausprobieren (wieviele Ports, wie großer MMIO Raum) diesen Speicher/Ports festlegen und das ist nicht so einfach.

Zitat von: svenska
Warum sollte der HDD-Treiber den gleichen RAM zweimal verbrauchen, nur weil du ihm keinen Block garantieren wolltest? In dem Moment hast du einen Cache am Stück und die Daten tauchen dann in 25 verschiedenen Speicherseiten auf und werden dorthin zusammengepopelt, ehe die Daten an deine Anwendung übergeben werden.
Hier habe ich wieder gar nicht verstanden was du meinst bzw. was du von mir willst ;)

Zitat von: svenska
der Netzwerktreiber muss nicht wissen, wo der HDD-Treiber die Sektoren hinspeichert. Was man mit dem Wissen machen kann, hatte ich oben schon geschrieben. Ist halt ne grundsätzliche Sache.
Da ist irgendwie ein Fehler drin! Bei einem Mikrokernel ist jeder Treiber ein eigenständiger User-Prozess. Der Netzwerktreiber bekommt also gar nicht raus wo der HDD-Treiber seine Sektoren hinspeichert! Der Netzwerktreiber kann nur innerhalb seines Prozesses gucken welche physische Adresse zu einer virtuellen gehört.

Zitat von: svenska
Was man mit dem Wissen machen kann, hatte ich oben schon geschrieben. Ist halt ne grundsätzliche Sache.
Sprich wenn obiges Problem nicht besteht kann man das mit dem Parsen so machen?!

Mal was anderes, wie kommt es das du hier ein Sicherheitsproblem siehst, bei der Sache ob ein Treiber aber falschen Speicher mappt nicht?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 06. September 2010, 20:07 »
Was du meinst ist linearer Adressraum und virtueller Adressraum! Physischer Speicher (wie der Name schon sagt) ist wirklich vorhandener RAM!
Und wenn du auf einem 32bit System 4GB RAM hast, dann belegt auch MMIO physischen RAM, was halt weniger schön, aber unvermeidbar ist.
Moment, Moment, Moment... Wir benutzen hier x86-Terminologie, oder? Dann bitte mal das Intel-Manual Teil 3a, Kapitel 3.1 anschauen (Memory Management Overview).

Virtuelle Adressen sind das, was das Programm sieht und bestehen aus einem Segment und Offset. An dieser Stelle haben wir die erste Übersetzung. Nachdem die Segmentierung erledigt ist, landen wir bei linearen Adressen. Und diese linearen Adressen wiederum werden mit Paging auf physische Adressen abgebildet.

Svenska meint hier also wirklich den physischen Adressraum, nicht den linearen.
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: 06. September 2010, 20:18 »
Naja, da wir aber auch von Flat-Memory ausgehen/reden ist der lineare Adressraum = 4GB. In dem Fall kann man also rein theoretisch linear und physisch gleichwertig verwenden.

Bei meiner Erklärung ist es aber einfacher zwischen wirklich vorhandenem RAM und einfach nur dem Adressraum zu unterscheiden ;)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 06. September 2010, 20:42 »
Nein, mit Flat Memory ist virtuell und linear dasselbe.
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: 06. September 2010, 20:46 »
Jap, muss dir recht geben, macht auch mehr Sinn, denn die virtuellen Adressen sind linear = zusammenhängend, aber die physischen müssen es nicht sein.

Scheiß Haarspalterei ;)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 06. September 2010, 20:59 »
Dafür sind meine Beiträge wenigstens kürzer als Eriks. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen