Ist jede Region im Diagramm ein Segment?
Dies sind zwei fast völlig unterschiedliche Verwendungen des Wortes "Segment".
- x86 Segmentation / Segmentregister: modernes x86 OSes verwenden , um ein flaches Speichermodell , bei dem alle Segmente die gleiche Basis haben = 0 und limit = max in 32-Bit - Modus das gleiche ist wie Hardware erzwingt , daß in 64-Bit - Modus , vestigial macht Segmentierungs Art von . (Mit Ausnahme von FS oder GS, die auch im 64-Bit-Modus für die Thread-lokale Speicherung verwendet werden.)
- Linker / Program-Loader Abschnitte / Segmente. ( Was ist der Unterschied zwischen Abschnitt und Segment im ELF-Dateiformat? )
Die Verbräuche hat einen gemeinsamen Ursprung: Wenn Sie wurden ein segmentierten Speicher - Modell (insbesondere ohne ausgelagertem virtuellen Speicher), könnten Sie Daten und BSS - Adressen das DS Segmentbasis, Stapel in Bezug auf die SS Basis und Code in Bezug auf dem relativen sein CS-Basisadresse.
So können mehrere unterschiedliche Programme auf unterschiedliche lineare Adressen geladen oder sogar nach dem Start verschoben werden, ohne die 16- oder 32-Bit-Offsets relativ zu den Segmentbasen zu ändern.
Aber dann muss man wissen, zu welchem Segment ein Zeiger relativ ist, also hat man "Fernzeiger" und so weiter. (Tatsächliche 16-Bit-x86-Programme mussten häufig nicht auf ihren Code als Daten zugreifen, sodass sie irgendwo ein 64-KByte-Codesegment und möglicherweise einen weiteren 64-KByte-Block mit DS = SS verwenden konnten die Unterseite (oder ein winziges Codemodell, bei dem alle Segmentbasen gleich sind).
Wie die x86-Segmentierung mit dem Paging interagiert
Die Adresszuordnung im 32/64-Bit-Modus lautet:
- segment: offset (Segmentbasis, die durch das Register impliziert wird, das den Offset enthält, oder mit einem Befehlspräfix überschrieben wird)
- 32 oder 64-Bit lineare virtuelle Adresse = Basis + Offset. (In einem flachen Speichermodell, wie es Linux verwendet, sind Zeiger / Offsets ebenfalls lineare Adressen. Außer beim Zugriff auf TLS relativ zu FS oder GS.)
Seitentabellen (zwischengespeichert durch TLB) werden linear auf 32 (Legacy-Modus), 36 (Legacy-PAE) oder 52-Bit-Adressen (x86-64) abgebildet. ( /programming/46509152/why-in-64bit-the-virtual-address-are-4-bits-short-48bit-long-compared-with-the ).
Dieser Schritt ist optional: Das Paging muss während des Startvorgangs durch Setzen eines Bits in einem Steuerregister aktiviert werden. Ohne Paging sind lineare Adressen physikalische Adressen.
Beachten Sie, dass Sie bei der Segmentierung nicht mehr als 32 oder 64 Bit des virtuellen Adressraums in einem einzelnen Prozess (oder Thread) verwenden können , da der flache (lineare) Adressraum, in den alles abgebildet wird, nur die gleiche Anzahl von Bits aufweist wie die Offsets selbst. (Dies war bei 16-Bit x86 nicht der Fall, bei dem die Segmentierung tatsächlich nützlich war, um mehr als 64 KB Speicher mit überwiegend 16-Bit-Registern und Offsets zu verwenden.)
Die CPU speichert Segmentdeskriptoren, die von der GDT (oder LDT) geladen wurden, einschließlich der Segmentbasis. Wenn Sie einen Zeiger dereferenzieren, wird, abhängig davon, in welchem Register er sich befindet, standardmäßig DS oder SS als Segment verwendet. Der Registerwert (Zeiger) wird als Versatz von der Segmentbasis behandelt.
Da die Segmentbasis normalerweise Null ist, machen CPUs dies in Sonderfällen. Oder aus einer anderen Perspektive, wenn Sie tun eine Basis nicht-Null - Segment haben, Lasten zusätzliche Latenz , da der „besondere“ (normal) Fall der Umgehung Zugabe der Basisadresse nicht gilt.
So richtet Linux x86-Segmentregister ein:
Die Basis und das Limit von CS / DS / ES / SS sind alle 0 / -1 im 32- und 64-Bit-Modus. Dies wird als flaches Speichermodell bezeichnet, da alle Zeiger auf denselben Adressraum verweisen.
(AMD-CPU-Architekten haben die Segmentierung neutralisiert, indem sie ein flaches Speichermodell für den 64-Bit-Modus erzwungen haben, da die Mainstream-Betriebssysteme es ohnehin nicht verwendeten, mit Ausnahme des No-Exec-Schutzes, der durch Paging mit PAE oder x86- 64 Seitentabellenformat.)
TLS (Thread Local Storage): FS und GS sind im Langmodus nicht auf base = 0 festgelegt. (Sie waren mit 386 neu und wurden von keiner Anweisung implizit verwendet, auch nicht von den rep
Anweisungen -string, die ES verwenden.) x86-64 Linux setzt die FS-Basisadresse für jeden Thread auf die Adresse des TLS-Blocks.
mov eax, [fs: 16]
Lädt z. B. einen 32-Bit-Wert aus 16 Bytes in den TLS-Block für diesen Thread.
Der CS-Segment-Deskriptor wählt aus, in welchem Modus sich die CPU befindet (16/32/64-Bit-Protected-Modus / Long-Modus). Linux verwendet einen einzelnen GDT-Eintrag für alle 64-Bit-User-Space-Prozesse und einen weiteren GDT-Eintrag für alle 32-Bit-User-Space-Prozesse. (Damit die CPU richtig funktioniert, müssen DS / ES und SS ebenfalls auf gültige Einträge gesetzt sein.) Es wird auch die Berechtigungsstufe (Kernel (Ring 0) vs. Benutzer (Ring 3)) ausgewählt, sodass der Kernel auch dann, wenn er zum 64-Bit-Benutzerraum zurückkehrt, dafür sorgen muss, dass CS sich ändert, indem er iret
oder sysret
anstelle eines normalen verwendet Sprung- oder Ret-Anweisung.
In x86-64 wird der syscall
Einstiegspunkt verwendet swapgs
, um GS vom GS des Benutzerbereichs zum Kernel zu spiegeln, mit dem der Kernelstapel für diesen Thread ermittelt wird. (Ein spezieller Fall von Thread-lokalem Speicher). Die syscall
Anweisung ändert den Stapelzeiger nicht so, dass er auf den Kernelstapel zeigt. Es zeigt immer noch auf den Benutzerstapel, wenn der Kernel den Einstiegspunkt 1 erreicht .
DS / ES / SS müssen ebenfalls auf gültige Segmentdeskriptoren eingestellt sein, damit die CPU im geschützten Modus / langen Modus arbeitet, obwohl die Basis / das Limit dieser Deskriptoren im langen Modus ignoriert werden.
Grundsätzlich wird die x86-Segmentierung für TLS und für das obligatorische x86-osdev-Zeug verwendet, das von der Hardware verlangt wird.
Fußnote 1: Spaßgeschichte: Es gibt Mailinglisten-Archive mit Nachrichten zwischen Kernel-Entwicklern und AMD-Architekten, die einige Jahre vor der Veröffentlichung von AMD64-Silizium erstellt wurden syscall
. Weitere Informationen finden Sie unter den Links in dieser Antwort .