Unter Paging versteht man die Aufteilung des gesamten theoretisch möglichen Adressraumes (Bit 32-Bit-Adressen sind dies 4 GB) in mehrere kleine Seiten (=Pages). Manche dieser Seiten werden normal im Speicher gehalten, und andere können ohne Probleme ausgelagert werden. Wenn nun auf eine ausgelagerte Page zugegriffen werden möchte, meldet dies der Prozessor, und der Speichermanager kann darauf reagieren und die Page wieder in den Speicher zurückladen. Diese Grundidee bedingt jedoch, dass der Prozessor Paging beherrscht, andernfalls funktioniert gar nichts.
Um das Paging detailierter zu behandeln, hier das Beispiel des i386:
Eine Adresse besteht aus 32 Bit und wird durch das Paging folgendermassen unterteilt (genannt wird sie in diesem Zustand lineare Adresse):
| f | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | f | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Directory | Page | Offset | |||||||||||||||||||||||||||||
Für ein Directory stehen 10 Bits zur Verfügung. 1024 Bytes adressierbar
Für eine Page stehen 10 Bits zur Verfügung. 1024 Bytes adressierbar
Für ein Offset stehen 12 Bits zur Verfügung: 4096 Bytes adressierbar
Jede Adresse wird also gebildet aus einem Verzeichnis, einer Seite und einem Offset. Im Speicher selbst (dazu mehr später) sind die Verzeichnis- und Page-Einträge irgendwo abgespeichert. Dies bedeutet, dass der Prozessor, wenn er eine solche Adresse bekommt, zuerst das richtige Verzeichnis auswählt, dort die richtige Seite sucht und dann zu der dort stehenden Adresse den Offset dazuzählt. Für den Prozessor bedeutet dies eigentlich viel Arbeit, ist aber trotzdem nach nur einem Taktzyklus erledigt (Prozessoren müssen aber eben diese Technologie auch anbieten), man kann also, wenn sich der Prozessor im Paging-Modus befindet, mit diesen Adressen ohne Zeitverlust wie mit jeder anderen arbeiten.
Nun zu den Verzeichnis- und Paging-Einträgen und dem Offset: Das Offset alleine kann als normale Adresse angeschaut werden. Es können also alle Bytes von 0 bis 4095 direkt adressiert werden. Allerding läuft heutzutage kein Computer mehr mit nur 4096 Bytes Speicher. Diese 4096 Bytes Speicher werden nun eben in eine Page zusammengefasst, eine Seite ist also stets 4096 Bytes lang und alle Pages stehen deshalb immer im Abstand von genau 4096 Bytes auseinander. Diese 4096 Bytes können aber nun zu einer sogenannten Page-Frame-Adresse hinzugezählt werden, welche sich in einer Page-Frame-Tabelle befindt. Diese Page-Frame-Adresse bezeichnet die absolute, also physikalische Adresse, an der diese Page beginnt. Haben wir also den Beginn einer Page an der Stelle 0x00050000 und ein Offset 0x0c1a, so ergibt sich daraus die physikalische Adresse 0x00050c1a.
Durch das Paging wurde festgelegt, dass die unteren 12 Bits eines Page-Frames (der Adresseintrag in der Page-Frame-Tabelle) nicht für die Adresse selbst gebraucht werden dürfen (diese 12 Bit werden ja durch das Offset geliefert). Die 12 Bits können nun benutzt werden, um ein Attribut zu speichern. Beim i386 ist beispielsweise das Bit 0 dafür da, festzulegen, ob die Page ausgelagert (0), oder im Speicher (1) ist. Bit 1 steht für nur lesen (0) oder lesen und schreiben (1). Bit 2 beinhaltet Schutzbestimmungen: 0=Supervisor, 1=User. Bit 5 ist 0, wenn diese Page noch nie benutzt wurde, andernfalls 1. Bit 6 schliesslich sagt aus, ob diese Page noch leer (0) oder bereits beschrieben (1) ist.
Diese Page-Frames stehen wie bereits gesagt in einer Page-Frame-Tabelle, oder kürzer, in einer Page-Table. Damit eine solche Page-Table im Speicher selbst gespeichert werden kann, muss sie genausogross sein, wie jede andere Page: 4096 Bytes. Sie beinhaltet somit 1024 Page-Frames, welche je 4 Byte benötigen. Diese Page-Frames sind in der Page-Table alle schön hintereinander aufgereiht und können somit vom Prozessor durch den Page-Eintrag in der linearen Adresse direkt gefunden werden. Was der Prozessor nun noch wissen muss, ist, wo sich nun diese Page-Tables wiederum befinden. Dazu dient der Directory-Eintrag der linearen Adresse. Wie man vermuten könnte, steht irgendwo im Speicher noch eine Page, welche 1024 Directory-Table-Einträge à 4 Bytes beinhaltet. Tatsächlich ist dem auch so: Diese, als wichtigste nicht-auslagerbare Page, steht dem Prozessor zu jeder Zeit zur Verfügung. Jeder Eintrag in dieser Directory-Table beinhaltet die absolute Adresse einer Page-Table, und dazu auch noch Zusatzinformationen (die gleichen, wie bei den normalen Pages, also ausgelagert, schreibgeschützt, ...). Das einzige, was der Prozessor also wissen muss, ist, wo sich die Directory-Table befindet. Er speichert diesen Wert in einem eigens dafür konstruierten Register, dem Page-Direcotry-Basisregister PDBR, welches auch mit der Abkürzung CR3 bezeichnet wird (Dank an M-M. S. für diese Korrektur).
Die Erklärung scheint sehr kompliziert, deswegen hier am besten ein Beispiel:
Der Prozessor bekommt die lineare Adresse 0xA63CF877.
Binär ausgedrückt 1010011000 1111001111 100001110111.
Zuerst die Aufteilung der Adresse:
| Der Directory-Eintrag ist | 1010011000 | = 0x298 | = 664 (Dezimal) |
| Der Page-Eintrag ist | 1111001111 | = 0x3CF | = 975 (Dezimal) |
| Der Offset-Eintrag ist | 100001110111 | = 0x877 | = 2167 (Dezimal) |
Der Eintrag im PDBR sei 0x00004000. Die Directory-Page befindet sich also an dieser Adresse. Nun sucht der Prozessor den 664-ten Eintrag (à 4 Bytes) dieser Page. Dazu rechnet er
0x00004000 + 664 * 4 = 0x00004a60
An dieser Adresse 0x00004a60 steht beispielsweise der Wert
0x0005d067 = 0000000000 0001011101 000001100111
Die untersten 12 Bits sagen aus, dass diese Page im Speicher, beschreibbar, für den User zugänglich, bereits benutzt und bereits beschrieben ist. Für die Adress-Berechnung benötigen wir diese Angaben jedoch nicht direkt und setzen die unteren 12 Bits auf Null, was folgende Adresse ergibt:
0x0005d000 = 0000000000 0001011101 000000000000
An dieser neu erhaltenen Adresse befindet sich unsere gesuchte Page-Tabelle. Nun sucht der Prozessor den 975-ten Eintrag (à 4 Bytes) dieser Page. Dazu rechnet er
0x0005d000 + 975 * 4 = 0x0005df3c
An dieser Adresse 0x0005df3c steht beispielsweise der Wert
0x004a4067 = 0000000001 0010100100 000001100111
Die unteren 12 Bits sagen wieder dasselbe aus, wie oben. Und wiederum setzen wir diese 12 Bits auf Null, wodurch wir nun folgende Adresse erhalten:
0x004a4000 = 0000000001 0010100100 000000000000
Nun wird der Offset noch dazugerechnet:
0x004a4000 + 2167 = 0x004a4877
Und dies ist die absolute physikalische Adresse, in Dezimalzahlen: 4'868'215