Paging — Änderungen 11373 → 11514

Zeile 6: Zeile 6:
  
 
== Funktionsweise ==
 
== Funktionsweise ==
−
Der virtuelle Speicher wird zunächst in gleich große Blöcke, so genannte Pages (Seiten), unterteilt. In der x86-Architektur sind dies Blöcke zu je vier Kilobytes. Einen Speicherkontext kann man sich vereinfacht als eine riesige Tabelle vorstellen, die jedem virtuellen Block einen gleich großen Block irgendwo im physischen Speicher zuweist. Diesen physischen Speicherblock nennt man auch ''Page Frame'' (dt. Seitenrahmen, oder seltener auch Seitenkachel).
+
Der virtuelle Speicher wird zunächst in gleich große Blöcke, so genannte Pages (Seiten), unterteilt. In den meisten Architekturen sind dies Blöcke zu je vier Kilobytes, manche bieten auch verschiedene Größen an. Einen Speicherkontext kann man sich vereinfacht als eine riesige Tabelle vorstellen, die jedem virtuellen Block einen gleich großen Block irgendwo im physischen Speicher zuweist. Diesen physischen Speicherblock nennt man auch ''Page Frame'' (dt. Seitenrahmen, oder seltener auch Seitenkachel).
  
 
Die folgende Tabelle dient als (von den Zahlen her völlig sinnfreie) Veranschaulichung dieser Übersetzung. Wenn das Programm jetzt auf die Speicheradresse 0x1234 zugreift, wird in Wirklichkeit auf die physische Adresse 0x3234 zugegriffen. Es muss nicht jede virtuelle Adresse ''gemappt'' (d. h. einer physischen Adresse zugewiesen) sein – der virtuelle Adressraum ist im Allgemeinen auch größer als der installierte physische Speicher (auf i386 beispielsweise 4 GB). Wird auf eine nicht gemappte Adresse zugegriffen, z. B. 0x25a2 im Beispiel, wird eine Exception (x86: [[Exception#Page Fault|Page Fault]]) ausgelöst.
 
Die folgende Tabelle dient als (von den Zahlen her völlig sinnfreie) Veranschaulichung dieser Übersetzung. Wenn das Programm jetzt auf die Speicheradresse 0x1234 zugreift, wird in Wirklichkeit auf die physische Adresse 0x3234 zugegriffen. Es muss nicht jede virtuelle Adresse ''gemappt'' (d. h. einer physischen Adresse zugewiesen) sein – der virtuelle Adressraum ist im Allgemeinen auch größer als der installierte physische Speicher (auf i386 beispielsweise 4 GB). Wird auf eine nicht gemappte Adresse zugegriffen, z. B. 0x25a2 im Beispiel, wird eine Exception (x86: [[Exception#Page Fault|Page Fault]]) ausgelöst.
Zeile 24: Zeile 24:
 
In der Praxis handelt es sich dabei nicht um eine einzige riesige Tabelle, die wie erwähnt zu großen Teilen ohnehin leer bleiben und Speicher verschwenden würde. Stattdessen benutzt man ein zwei- oder mehrstufiges System.
 
In der Praxis handelt es sich dabei nicht um eine einzige riesige Tabelle, die wie erwähnt zu großen Teilen ohnehin leer bleiben und Speicher verschwenden würde. Stattdessen benutzt man ein zwei- oder mehrstufiges System.
  
−
Beim i386 bildet ein ''Page Directory'' einen Speicherkontext ab. Dabei handelt es sich um eine Tabelle, die virtuellen Speicherblöcken von 4 MB Größe die physische Adresse einer ''Page Table'' zuweist oder den Speicherbereich als frei markiert.
+
== In physischen Speicher schreiben ==
 +
Wenn nun Paging eingeschaltet ist, kann man nicht mehr in den physischen Speicher schreiben. Wenn man nicht viel physischen Speicher hat, oder 64 Bit benutzt und deswegen der virtuelle Adressraum groß genug ist, kann man den gesamten physischen Speicher in den virtuellen mappen.
 +
 
 +
Es besteht aber auch die Möglichkeit, Zugriff auf den gesamten physischen Speicher zu haben, ohne dass man ihn direkt mappt. Erstmal braucht man eine Möglichkeit das Page Directory und die Page Tables noch zu ändern nachdem Paging eingeschaltet wurde. Wenn man dies kann, kann man sich einfach immer die gerade gebrauchte physische Page auf eine festgelegte virtuelle Page mappen und voilà. Um nun Zugriff auf das Page Directory und die Page Tables zu haben, kann man einfach z. B. als letzte Page Table das Page Directory selbst eintragen. Das Page Directory wird dann als Page Table interpretiert und alle Page Tables als Pages in den Speicher gemappt. Somit enthalten die letzten 4 MB des virtuellen Speichers die Page Tables, wobei die letzten 4 kB das Page Directory enthalten.
 +
 
 +
== Paging im x86 Protected Mode ==
 +
 
 +
Beim i386 bildet ein ''Page Directory'' (PD) einen Speicherkontext ab. Dabei handelt es sich um eine Tabelle, die virtuellen Speicherblöcken von 4 MB Größe die physische Adresse einer ''Page Table'' (PT) zuweist oder den Speicherbereich als frei markiert.
  
−
Die Page Table ist anschließend dafür zuständig, innerhalb „ihrer“ 4 MB die Zuordnung der einzelnen 4K-Pages vorzunehmen. Beim Zugriff auf die Adresse 0x456789 wird also zunächst festgestellt, dass die Pagetable für den Bereich 4 bis 8 MB zuständig ist (0x400000 sind 4 MB), und ihre Adresse im Page Directory nachgeschlagen. Anschließend wird innerhalb der Page Table nachgeschlagen, was die physische Adresse für die Bytes 0x56000 bis 0x56fff dieses 4-MB-Blocks ist. Angenommen, die Page Table ordnet diesen die physische Adresse 0xabcde000 zu, dann liegt der gesuchte Speicher an 0xabcde789.
+
Die Page Table ist anschließend dafür zuständig, innerhalb „ihrer“ 4 MB die Zuordnung der einzelnen 4K-Pages vorzunehmen. Beim Zugriff auf die Adresse 0x456789 wird also zunächst festgestellt, dass die Page-Table für den Bereich 4 bis 8 MB zuständig ist (0x400000 sind 4 MB), und ihre Adresse im Page Directory nachgeschlagen. Anschließend wird innerhalb der Page Table nachgeschlagen, was die physische Adresse für die Bytes 0x56000 bis 0x56fff dieses 4-MB-Blocks ist. Angenommen, die Page Table ordnet diesen die physische Adresse 0xabcde000 zu, dann liegt der gesuchte Speicher an 0xabcde789.
  
 
Wie die CPU aus einer virtuellen die zugeordnete physische Adresse berechnet, soll folgende Grafik zeigen:
 
Wie die CPU aus einer virtuellen die zugeordnete physische Adresse berechnet, soll folgende Grafik zeigen:
Zeile 40: Zeile 47:
 
(''Hinweis:'' Bei Schritt 3 kann der Eintrag auch direkt auf einen 4MB Bereich ("Large Page") zeigen, siehe hierzu [[Page Size Extension]])
 
(''Hinweis:'' Bei Schritt 3 kann der Eintrag auch direkt auf einen 4MB Bereich ("Large Page") zeigen, siehe hierzu [[Page Size Extension]])
  
−
== Einschalten des Paging-Mechanismus ==
+
=== Einschalten des Paging-Mechanismus ===
 
Zum Einschalten des Paging-Mechanismus auf der x86-Architektur muss man Bit-31 im CR0-Register setzen. Davor muss aber ein gültiges Page-Directory angelegt und dessen physische Adresse im CR3-Register abgelegt worden sein.
 
Zum Einschalten des Paging-Mechanismus auf der x86-Architektur muss man Bit-31 im CR0-Register setzen. Davor muss aber ein gültiges Page-Directory angelegt und dessen physische Adresse im CR3-Register abgelegt worden sein.
  
−
== Page-Directory ==
+
=== Aufbau Page Directory (PD) ===
−
Ein Pagedirectory enthält 1024 Eintrage à vier Byte. Ein Pagedirectory-Eintrag kann jeweils auf ein Pagetable zeigen. Pagedirectories (wie auch Pagetables) müssen immer 4k-aligned sein, d. h. sie füllen genau eine Page aus.
+
Ein Page-Directory (PD) enthält 1024 Einträge à vier Byte. Ein PD-Eintrag kann jeweils auf eine Page-Table zeigen. PDs (wie auch PTs) müssen immer 4k-aligned sein, d. h. sie füllen genau eine Page aus.
  
 
{| {{prettytable}}
 
{| {{prettytable}}
Zeile 72: Zeile 79:
 
|}
 
|}
  
−
== Page Tables ==
+
=== Aufbau Page Table (PT) ===
 
Eine Page Table enthält 1024 Einträge à vier Byte. Jeder Eintrag zeigt auf eine physische Page. Page Tables müssen 4k-aligned sein und füllen somit eine ganze Page.
 
Eine Page Table enthält 1024 Einträge à vier Byte. Jeder Eintrag zeigt auf eine physische Page. Page Tables müssen 4k-aligned sein und füllen somit eine ganze Page.
  
Zeile 101: Zeile 108:
 
|}
 
|}
  
−
== Translation Lookaside Buffer ==
+
Wer genau hinsieht, bemerkt vermutlich, dass die Struktur von PD und PT quasi identisch ist, einzelne Felder nur andere Bedeutungen haben. Die Umsetzung im Quellcode kann also gleich sein (das selbe C-struct bspw.).
 +
 
 +
=== Translation Lookaside Buffer ===
 
Der Prozessor benutzt für das Auflösen der virtuellen Adressen eine Art Cache für die zuletzt benutzten Pages, den sogenannten ''Translation Lookaside Buffer'' oder TLB. Für den Programmierer spielt dieser TLB dann eine Rolle, wenn das Mapping einer Page geändert wird, aber der Prozessor möglicherweise noch die alte physische Adresse im TLB behalten hat.
 
Der Prozessor benutzt für das Auflösen der virtuellen Adressen eine Art Cache für die zuletzt benutzten Pages, den sogenannten ''Translation Lookaside Buffer'' oder TLB. Für den Programmierer spielt dieser TLB dann eine Rolle, wenn das Mapping einer Page geändert wird, aber der Prozessor möglicherweise noch die alte physische Adresse im TLB behalten hat.
  
Zeile 108: Zeile 117:
 
Man invalidiert den TLB mit „invlpg <address>“. Wobei <address> eine virtuelle Adresse innerhalb der von der Änderung betroffenen Page ist. invlpg ist ab dem 486 vorhanden. Beim Neuladen des [[Steuerregister|Steuerregisters]] CR3 wird der TLB ebenfalls komplett geleert (Achtung, das geht natürlich auf die Performance).
 
Man invalidiert den TLB mit „invlpg <address>“. Wobei <address> eine virtuelle Adresse innerhalb der von der Änderung betroffenen Page ist. invlpg ist ab dem 486 vorhanden. Beim Neuladen des [[Steuerregister|Steuerregisters]] CR3 wird der TLB ebenfalls komplett geleert (Achtung, das geht natürlich auf die Performance).
  
−
== Speicher mappen ==
+
=== Speicher mappen ===
 
Um eine beliebige virtuelle Adresse auf eine beliebige physische Adresse zu mappen, muss man erst den richtigen Eintrag im Page Directory und in der Page Table berechnen, um schließlich die physische Page (mit den passenden Flags) in der Page Table eintragen zu können. Es wird immer von virtuell nach physisch zugeordnet, d.&nbsp;h. wenn man 0xB8000 (phys.) auf 0x12345000 (virt.) mappen will, muss man erst den Page-Directory- und Page-Table-Eintrag von 0x12345000 berechnen. Das geht am besten so:
 
Um eine beliebige virtuelle Adresse auf eine beliebige physische Adresse zu mappen, muss man erst den richtigen Eintrag im Page Directory und in der Page Table berechnen, um schließlich die physische Page (mit den passenden Flags) in der Page Table eintragen zu können. Es wird immer von virtuell nach physisch zugeordnet, d.&nbsp;h. wenn man 0xB8000 (phys.) auf 0x12345000 (virt.) mappen will, muss man erst den Page-Directory- und Page-Table-Eintrag von 0x12345000 berechnen. Das geht am besten so:
−
<c>Pagedirectory_Eintrag =  virtuelle_adresse >> 22          (= 0x48)
 
−
Pagetable_Eintrag    = (virtuelle_adresse >> 12) % 1024  (= 0x345)</c>
 
−
Nun suche man erst die Adresse der Page Table (im eben berechneten ''Pagedirectory_Eintrag'' schauen). '''Achtung:''' Es handelt sich hier um die physische Adresse.
 
−
Mit der Adresse der Page Table kann man jetzt in den ''Pagetable_Eintrag'' die physische Adresse eintragen, die passenden Flags setzen und schon ist die Page gemappt.
 
  
−
== In physischen Speicher schreiben ==
+
<syntaxhighlight lang="c">
−
Wenn nun Paging eingeschaltet ist, kann man nicht mehr in den physischen Speicher schreiben. Wenn man nicht viel physischen Speicher hat, oder 64 Bit benutzt und deswegen der virtuelle Adressraum groß genug ist, kann man den gesamten physischen Speicher in den virtuellen mappen.
+
virtuelle_adresse = 0x12345000;
 +
pd_eintrag =  virtuelle_adresse >> 22          (= 0x48)
 +
pt_eintrag = (virtuelle_adresse >> 12) % 1024  (= 0x345)
 +
</syntaxhighlight>
 +
 
 +
Zuerst wird die Adresse der Page Table (im eben berechneten ''PD Eintrag'' schauen). '''Achtung:''' Es handelt sich hier um die physische Adresse.
 +
Mit der Adresse der Page Table kann man jetzt in den ''PT Eintrag'' die physische Adresse eintragen, die passenden Flags setzen und schon ist die Page gemappt.
 +
 
 +
=== Page Address Extension (PAE) ===
 +
 
 +
In aktuellen x86 CPUs (seit dem Pentium Pro / Pentium II) gibt es auch noch eine Erweiterung für Paging im Protected Mode: die Page Address Extensions. Diese erlauben den Zugriff auf mehr physischen Speicher, indem die Einträge in PD und PT auf jeweils 8 Byte (64 bit) erweitert werden. Damit die Tabellen trotzdem nur jeweils 4KB groß sind, wurde die Anzahl an Einträgen halbiert. Da das nun auch den virtuellen Adressraum verkleinern würde, wurde eine weitere Ebene eingefügt: die ''Page Directory Pointer'' (PDP) Tabelle. Diese zeigt auf die einzelnen ''Page Directory'' Tabellen, die ja wiederum auf die einzelnen ''Page Table''s zeigen.
 +
 
 +
Der Aufbau der PDP Tabelle entspricht weitestgehend dem Aufbau der PD Tabelle, es gibt aber nur 4 Einträge (also 2 Bit der virtuellen Adresse). Zusammen mit jeweils 512 Einträgen (je 9 Bit der virtuellen Adresse) der nun kleineren PDs und PTs kommen wir so trotzdem auf 20 Bit der virtuellen Adresse.
  
−
Es besteht aber auch die Möglichkeit, Zugriff auf den gesamten physischen Speicher zu haben, ohne dass man ihn direkt mappt. Erstmal braucht man eine Möglichkeit das Page Directory und die Page Tables noch zu ändern nachdem Paging eingeschaltet wurde. Wenn man dies kann, kann man sich einfach immer die gerade gebrauchte physische Page auf eine festgelegte virtuelle Page mappen und voilà. Um nun Zugriff auf das Page Directory und die Page Tables zu haben, kann man einfach z.&nbsp;B. als letzte Page Table das Page Directory selbst eintragen. Das Page Directory wird dann als Page Table interpretiert und alle Page Tables als Pages in den Speicher gemappt. Somit enthalten die letzten 4&nbsp;MB des virtuellen Speichers die Page Tables, wobei die letzten 4&nbsp;kB das Page Directory enthalten.
+
==== Aufbau Page Directory Pointer (PDP)====
  
−
==Paging im Long Mode==
+
Ein PDP enthält 512 Eintrage à acht Byte. Ein PDP-Eintrag kann jeweils auf ein Page Directory zeigen.
−
Das Paging im Long Mode gestaltet sich etwas schwieriger als das Paging im Protected Mode. Dies liegt zunächst einmal daran, dass im Long Mode nicht nur zwei Ebenen existieren, sondern bis zu vier.
 
  
−
===Page-Map Level-4 Table===
 
−
Eine Page-Map Level-4 Table enthält 512 Eintrage à acht Byte. Ein Page-Map Level-4 Table-Eintrag kann jeweils auf eine Page-Directory Pointer Table zeigen.
 
 
{|{{prettytable}}
 
{|{{prettytable}}
 
! Bit || Funktion
 
! Bit || Funktion
 
|-
 
|-
−
| 0 || Gibt an, ob die Page momentan im Speicher liegt. Ist das Bit gelöscht (Page nicht im Speicher), dann sind alle anderen Bits für das Betriebssystem frei verfügbar und können z. B. für Swapping genutzt werden.  
+
| 0 || Gibt an, ob die Page momentan im Speicher liegt. Ist das Bit gelöscht (Page nicht im Speicher), dann sind alle anderen Bits für das Betriebssystem frei verfügbar und können z.&nbsp;B. für Swapping genutzt werden.  
 
|-
 
|-
 
| 1 || Wenn dieses Bit gesetzt ist, kann die Page beschrieben werden. Ansonsten kann die Page nur gelesen werden.  
 
| 1 || Wenn dieses Bit gesetzt ist, kann die Page beschrieben werden. Ansonsten kann die Page nur gelesen werden.  
Zeile 138: Zeile 152:
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
|-
 
|-
−
| 5 || Wird von der CPU gesetzt, wenn die Page-Map Level-4 Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
+
| 5 || Wird von der CPU gesetzt, wenn die Page-Directory Pointer Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
 
|-
 
|-
 
| 6 || Wird ignoriert und sollte 0 sein.
 
| 6 || Wird ignoriert und sollte 0 sein.
 
|-
 
|-
−
| 7-8 || Muss 0 sein.
+
| 7 || Muss 0 sein, wenn 2-MiB-Pages oder 4-KiB-Pages verwendet werden, muss 1 sein, wenn 1-GiB-Pages verwendet werden.
 +
|-
 +
| 8 || Wenn CR4.PGE und Bit 7 auf 1 gesetzt sind, gibt das Bit an, ob die Page global ist (Nicht durch Instruktionen wie mov cr3 geflusht wird). Muss ansonsten 0 sein.
 
|-
 
|-
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
|-
 
|-
−
| 12-51 || Gibt die physische Adresse der Page-Directory Pointer Table an.
+
| 12-51 || Gibt die physische Adresse der Page-Directory Table an. Gibt die physische Adresse der Page Table an. Besteht alternativ aus der physischen Adresse der Page (Bits 30 – 51), dem höchsten PAT-Bit (Bit 12, sollte 0 sein wenn nicht benötigt) und reservierten Bits (Bit 13 – 29), wenn 1-GiB-Pages verwendet werden.
 
|-
 
|-
 
| 52-62 || Diese Bits sind frei verfügbar.
 
| 52-62 || Diese Bits sind frei verfügbar.
Zeile 153: Zeile 169:
 
|}
 
|}
  
−
===Page-Directory Pointer Table===
+
==== Aufbau Page Directory (PD) ====
−
Eine Page-Directory Pointer Table enthält 512 Eintrage à acht Byte. Ein Page-Directory Pointer Table-Eintrag kann jeweils auf eine Page-Directory Table zeigen.
+
Ein Page Directory enthält 512 Eintrage à acht Byte. Ein PD-Eintrag kann jeweils auf eine Page Table zeigen.
 +
 
 
{|{{prettytable}}
 
{|{{prettytable}}
 
! Bit || Funktion
 
! Bit || Funktion
Zeile 168: Zeile 185:
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
|-
 
|-
−
| 5 || Wird von der CPU gesetzt, wenn die Page-Directory Pointer Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
+
| 5 || Wird von der CPU gesetzt, wenn die Page-Directory Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
 
|-
 
|-
 
| 6 || Wird ignoriert und sollte 0 sein.
 
| 6 || Wird ignoriert und sollte 0 sein.
 
|-
 
|-
−
| 7 || Muss 0 sein, wenn 2-MiB-Pages oder 4-KiB-Pages verwendet werden, muss 1 sein, wenn 1-GiB-Pages verwendet werden.
+
| 7 || Muss 0 sein, wenn 1-GiB-Pages oder 4-KiB-Pages verwendet werden, muss 1 sein, wenn 2-MiB-Pages verwendet werden.
 
|-
 
|-
 
| 8 || Wenn CR4.PGE und Bit 7 auf 1 gesetzt sind, gibt das Bit an, ob die Page global ist (Nicht durch Instruktionen wie mov cr3 geflusht wird). Muss ansonsten 0 sein.
 
| 8 || Wenn CR4.PGE und Bit 7 auf 1 gesetzt sind, gibt das Bit an, ob die Page global ist (Nicht durch Instruktionen wie mov cr3 geflusht wird). Muss ansonsten 0 sein.
Zeile 178: Zeile 195:
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
|-
 
|-
−
| 12-51 || Gibt die physische Adresse der Page-Directory Table an. Gibt die physische Adresse der Page Table an. Besteht alternativ aus der physischen Adresse der Page (Bits 30 – 51), dem höchsten PAT-Bit (Bit 12, sollte 0 sein wenn nicht benötigt) und reservierten Bits (Bit 13 – 29), wenn 1-GiB-Pages verwendet werden.
+
| 12-51 || Gibt die physische Adresse der Page Table an. Besteht alternativ aus der physischen Adresse der Page (Bits 21 – 51), dem höchsten PAT-Bit (Bit 12, sollte 0 sein wenn nicht benötigt) und reservierten Bits (Bit 13 – 20), wenn 2-MiB-Pages verwendet werden.
 
|-
 
|-
 
| 52-62 || Diese Bits sind frei verfügbar.
 
| 52-62 || Diese Bits sind frei verfügbar.
Zeile 185: Zeile 202:
 
|}
 
|}
  
−
===Page-Directory Table===
+
==== Aufbau Page Table (PT) ====
−
Eine Page-Directory Table enthält 512 Eintrage à acht Byte. Ein Page-Directory Table-Eintrag kann jeweils auf eine Page Table zeigen.
+
Eine Page Table enthält 512 Eintrage à acht Byte. Ein PT-Eintrag kann jeweils auf eine Page zeigen.
 +
 
 
{|{{prettytable}}
 
{|{{prettytable}}
 
! Bit || Funktion
 
! Bit || Funktion
Zeile 200: Zeile 218:
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
|-
 
|-
−
| 5 || Wird von der CPU gesetzt, wenn die Page-Directory Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
+
| 5 || Wird von der CPU gesetzt, wenn die Page Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
 
|-
 
|-
 
| 6 || Wird ignoriert und sollte 0 sein.
 
| 6 || Wird ignoriert und sollte 0 sein.
 
|-
 
|-
−
| 7 || Muss 0 sein, wenn 1-GiB-Pages oder 4-KiB-Pages verwendet werden, muss 1 sein, wenn 2-MiB-Pages verwendet werden.
+
| 7 || Höchstes PAT-Bit. Sollte 0 sein wenn nicht benötigt.
 
|-
 
|-
 
| 8 || Wenn CR4.PGE und Bit 7 auf 1 gesetzt sind, gibt das Bit an, ob die Page global ist (Nicht durch Instruktionen wie mov cr3 geflusht wird). Muss ansonsten 0 sein.
 
| 8 || Wenn CR4.PGE und Bit 7 auf 1 gesetzt sind, gibt das Bit an, ob die Page global ist (Nicht durch Instruktionen wie mov cr3 geflusht wird). Muss ansonsten 0 sein.
Zeile 210: Zeile 228:
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
|-
 
|-
−
| 12-51 || Gibt die physische Adresse der Page Table an. Besteht alternativ aus der physischen Adresse der Page (Bits 21 – 51), dem höchsten PAT-Bit (Bit 12, sollte 0 sein wenn nicht benötigt) und reservierten Bits (Bit 13 – 20), wenn 2-MiB-Pages verwendet werden.
+
| 12-51 || Gibt die physische Adresse der Page an wenn 4-KiB-Pages verwendet werden.
 
|-
 
|-
 
| 52-62 || Diese Bits sind frei verfügbar.
 
| 52-62 || Diese Bits sind frei verfügbar.
Zeile 217: Zeile 235:
 
|}
 
|}
  
−
===Page Table===
+
Auch mit aktiviertem PAE sehen die einzelnen Tabellen quasi komplett identisch aus, der einzige Unterschied ist die Interpretierung mancher Felder. Auch hier kann also die Implementierung im Quellcode auf die gleiche Datenstruktur zurückgreifen, beispielsweise ein [[C]]-struct ''PagingEntry'' und ein typedef von ''PagingTable'' auf <code>PagingEntry[512]</code> (siehe LF OS unten in den Links).
−
Eine Page Table enthält 512 Eintrage à acht Byte. Ein Page Table-Eintrag kann jeweils auf eine Page zeigen
+
 
 +
== Paging im x86 Long Mode ==
 +
 
 +
Das Paging im Long Mode gestaltet sich etwas schwieriger als das Paging im Protected Mode, setzt aber auf dem PAE Paging im Protected Mode auf. Aufbauend auf PAE wurden folgende Dinge geändert:
 +
 
 +
* die PDP Tabelle enthält nun die vollen 512 Einträge, also 9 Bit der virtuellen Adresse (statt bisher 4 Einträge/2 Bit) -> wir kommen nun auf 39 Bit virtuellen Adressraum (3*9 Bits durch die Ebenen + 12 Bit Offset innerhalb der Page), also 512 GB nutzbaren Virtuellen Speicher.
 +
* vor der PDP wurde eine weitere Ebene eingefügt, die Page-Map Level 4 Tabelle (PML4) - ab hier werden die Ebenen einfach durchnummeriert. Noch eine Ebene mehr, also nun 48 Bit virtueller Adressraum -> 256 TB.
 +
 
 +
Das ist aber nur die erste Ausbaustufe von amd64. Über eine bestimmte [[CPUID]] lässt sich die Anzahl der unterstützten virtuellen Adressbits abrufen, woraus sich die Anzahl der Mapping-Ebenen ableiten lässt (<39 -> 3 Ebenen, <48 -> 4 Ebenen, <57 -> 5 Ebenen, ...).
 +
 
 +
===PMLx Tabellen===
 +
 
 +
Der Aufbau der PMLx (PML4, PML5, ..) ist zum Glück immer gleich und sogar wieder sehr ähnlich zu Page Directory und Page Table: 512 Einträge mit jeweils 8 Byte. Ein Eintrag zeigt jeweils auf die Ebene darunter, PML5 Einträge also auf PML4s, PML4-Einträge also auf PDPs.
 +
 
 
{|{{prettytable}}
 
{|{{prettytable}}
 
! Bit || Funktion
 
! Bit || Funktion
 
|-
 
|-
−
| 0 || Gibt an, ob die Page momentan im Speicher liegt. Ist das Bit gelöscht (Page nicht im Speicher), dann sind alle anderen Bits für das Betriebssystem frei verfügbar und können z.&nbsp;B. für Swapping genutzt werden.  
+
| 0 || Gibt an, ob die Page momentan im Speicher liegt. Ist das Bit gelöscht (Page nicht im Speicher), dann sind alle anderen Bits für das Betriebssystem frei verfügbar und können z. B. für Swapping genutzt werden.  
 
|-
 
|-
 
| 1 || Wenn dieses Bit gesetzt ist, kann die Page beschrieben werden. Ansonsten kann die Page nur gelesen werden.  
 
| 1 || Wenn dieses Bit gesetzt ist, kann die Page beschrieben werden. Ansonsten kann die Page nur gelesen werden.  
Zeile 232: Zeile 263:
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
| 4 || Wenn dieses Bit gesetzt ist, wird für die Page kein Cache benutzt.  
 
|-
 
|-
−
| 5 || Wird von der CPU gesetzt, wenn die Page Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
+
| 5 || Wird von der CPU gesetzt, wenn die Page-Map Level-4 Table benutzt wurde. Dieses Bit wird allerdings nicht von der CPU zurückgesetzt.  
 
|-
 
|-
 
| 6 || Wird ignoriert und sollte 0 sein.
 
| 6 || Wird ignoriert und sollte 0 sein.
 
|-
 
|-
−
| 7 || Höchstes PAT-Bit. Sollte 0 sein wenn nicht benötigt.
+
| 7-8 || Muss 0 sein.
−
|-
 
−
| 8 || Wenn CR4.PGE und Bit 7 auf 1 gesetzt sind, gibt das Bit an, ob die Page global ist (Nicht durch Instruktionen wie mov cr3 geflusht wird). Muss ansonsten 0 sein.
 
 
|-
 
|-
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
| 9-11 || Diese Bits sind frei verfügbar. Sie können z.&nbsp;B. genutzt werden um Pages zu markieren, die zwar im Speicher liegen, aber auch schon auf einen Swapmedium existieren, so dass sie ohne weiteres geswappt werden können, und/oder um Pages zu markieren, die nicht ausgelagert werden dürfen.
 
|-
 
|-
−
| 12-51 || Gibt die physische Adresse der Page an wenn 4-KiB-Pages verwendet werden.
+
| 12-51 || Gibt die physische Adresse der Page-Directory Pointer Table an.
 
|-
 
|-
 
| 52-62 || Diese Bits sind frei verfügbar.
 
| 52-62 || Diese Bits sind frei verfügbar.
Zeile 248: Zeile 277:
 
| 63 || Wenn EFER.NXE auf 1 gesetzt ist gibt dieses Bit an, ob das Ausführen von Code in der Page erlaubt ist (0) oder nicht (1). Wenn EFER.NXE auf 0 gesetzt ist und das Bit auf 1 gesetzt ist wird ein Pagefault ausgelöst.
 
| 63 || Wenn EFER.NXE auf 1 gesetzt ist gibt dieses Bit an, ob das Ausführen von Code in der Page erlaubt ist (0) oder nicht (1). Wenn EFER.NXE auf 0 gesetzt ist und das Bit auf 1 gesetzt ist wird ein Pagefault ausgelöst.
 
|}
 
|}
 +
 +
Die PDPs, PDs und PTs entsprechen denen des Protected Mode mit aktiviertem PAE (weswegen im Long Mode auch immer PAE aktiviert ist).
 +
  
 
== Weiterführende Artikel ==
 
== Weiterführende Artikel ==
Zeile 257: Zeile 289:
 
* [[Ausgabe_8#Paging|Ausgabe 8]]
 
* [[Ausgabe_8#Paging|Ausgabe 8]]
 
* http://osdever.net/tutorials/pdf/basic_paging.pdf
 
* http://osdever.net/tutorials/pdf/basic_paging.pdf
 +
* https://littlefox.narf.press/lf-os_amd64/vm_8c.html#structvm__table__entry - Gemeinsame Datenstruktur für alle Paging-Ebenen (LF OS)
 +
  
 
[[Category:Tutorials]]
 
[[Category:Tutorials]]