Hallo,
Adresse beginnt immer bei 0x00
Der virtuelle Adress-Raum, im Flat-Model, beginnt zwar bei 0 aber die 0-te Page lässt man für gewöhnlich ungemappt damit ein NULL-Pointer eine Exception wirft.
das OS gibt vor wo der Code anfängt
ja, das stimmt, kann man übrigens auch bei Segmentierung so machen
das Programm muss sich selbst kümmern ob das sich Stack, Code und Daten nicht in die Quere kommen.
Der Linker markiert das im Executable-File als Sektionen so das diese Unterscheidung der Executable-Loader vom OS passend treffen kann, der verteilt dann alles vernünftig im virtuellem Adress-Raum vom neu zu erstellendem Task.
jede Änderung des Limits kann nur das OS über Systemaufrufe
jeder Zugriff außerhalb des Speicherlimits muss eine Exception werfen
Im Flat-Memory-Model gibt es kein Limit. Es gibt nur ungemappte bzw. unberechtigte (z.B. Kernel-Space) Bereiche im linearen Adress-Raum eines Task.
Wenn nun dieser Speicher im Hitergrund in mehrere Pages zerteilt ist das erstmal egal.
Davon merkt das User-Task ja gar nichts.
Sind aber nun mit diesen Seiten mit unterschiedlichen Attributen verknüpft (NoeXecute, ReadOnly) so ist das ziemlich merkwürdig.
Das ist nicht "merkwürdig" sondern der einzigste Weg wenigstens ein bisschen Sicherheit innerhalb eines Task zu etablieren. Die Task untereinander können sich ja aufgrund der unterschiedlichen Adress-Räume eh nicht in die Quere kommen.
Diese Page-Attribute werden anhand der Sektions-Eigenschaften aus dem Executable-File passend gesetzt, sind also etwas was Compiler bzw. Linker direkt beeinflussen können.
jedes Segment beginnt auch bei 0x00
Beim 386-PM ja, deshalb kann man dort die Null-Pointer-Exception nicht so zuverlässig implementieren. Auf meiner Zielplatform gibt es für jedes Segment nicht nur ein individuelles Limit sondern auch ein kleines individuelles Minimum, damit werden zwar in jedem Segment ein paar (wenige) Bytes verschwendet aber dafür gibts zuverlässige Null-Pointer-Exceptions.
jedes Segment soll keine Überlappung in ein anderes Segment haben
Richtig. Es gibt aber ein paar Ausnahmen, z.B. muss ein Debugger für das Code-Segment seines Client-Programms ein Alias-Daten-Segment (mit der selben Basis und dem selben Limit) erstellen damit er überhaupt den Programm-Code sieht (sonst gäbe es keine Disassembler-Ansicht) da das Code-Segment ja Executable-Only ist (also nicht lesbar und erst recht nicht schreibbar). Aber Teil-Überlappungen, so wie im 8086-RM, soll es aber definitiv nicht geben.
Zugriffe außerhalb der Segmente müssen auch dann eine Exception werfen wenn sie in einem anderen gültigen Segment landen
Was genau meinst du damit?
Das User-Task weis nicht wo seine Segmente im linearen Adress-Raum liegen (das kann sich sogar mit der Zeit ändern) also gibt es keine Beziehungen der Segmente untereinander. Die CPU selber wird jedenfalls nicht prüfen ob ein Offset das aus einem Segment raus ragt in ein anderes rein fällt.
far-Pointer sind eigentlich nicht nötig
Irgendwie muss ja ein allgemein geltendes Stück Programm-Code einem Pointer ansehen welches Segment gemeint ist. Dazu dient der Selector-Teil in einem FAR-Pointer.
sondern nur Segment-Override-Präfixe
Dafür gibt es nicht genügend Segment-Register, auf keiner CPU. Ein Task benötigt eine ganze Reihe an Segmenten. Schau die mal die Menge an Sektionen in einem typischen Executable-File an.
Für beide Modelle muss gelten das der schreibende Zugriff auf die Deskriptoren eine Exception wirft
Auch bei Lese-Zugriffen sollte eine Exception kommen, sonst könnte ja ein Programm die Internas von anderen Programmen, oder gar dem OS, ausspionieren.
Und was hindert uns als OS-Designer daran beide Modelle im fertigen OS anzubieten.
Auf einem vorhandenen Flat-Memory-OS ein segmentiertes Programm laufen zu lassen stelle ich mir quasi unmöglich vor. Umgedreht sollte es gehen auch wenn es einiges an Arbeit kostet und natürlich alle Vorteile der Segmentierung wegfallen, wenn das OS dann noch das Paging ausschaltet (weil nicht benötigt) dann sind alle Schutzmechanismen weg und das Flat-Memory-Task läuft noch unsicherer als auf dem primitivsten Flat-Memory-OS.
Wenn Du wirklich ein OS für beide Memory-Modelle entwickeln möchtest dann nur zu, ich würde mich über Source-Code (natürlich nur zum inspirieren lassen) sehr freuen.
Grüße
Erik