Eine detaillierte Einführung in die Speicherverwaltung und -adressierung unter Linux

Eine detaillierte Einführung in die Speicherverwaltung und -adressierung unter Linux

1. Konzept

Speicherverwaltungsmodus

Segmenttyp: Der Speicher ist in mehrere Segmente unterteilt, jedes Segment ist ein kontinuierlicher Speicher und unterschiedliche Segmente entsprechen unterschiedlichen Verwendungszwecken. Die Größe jedes Segments ist nicht einheitlich, was zu Problemen wie Speicherfragmentierung und ineffizientem Speicheraustausch führen kann.

Paged: Der Speicher wird zur Verwaltung in mehrere Speicherseiten aufgeteilt. Beispielsweise beträgt in einem Linux-System die Größe jeder Seite 4KB . Durch die Paging-Funktion entstehen keine kleinen Speicherfragmente. Allerdings besteht weiterhin das Problem der Speicherfragmentierung.

Absatz-Seitenformat: eine Kombination aus Absatzformat und Seitenformat.

Adresstypklassifizierung

Logische Adresse: Die vom Programm verwendete Adresse, normalerweise die Adresse, die nicht vom Segmentspeichermanagement zugeordnet ist, wird als logische Adresse bezeichnet

Lineare Adresse: Die durch segmentierte Speicherverwaltung zugeordnete Adresse wird als lineare Adresse oder auch als virtuelle Adresse bezeichnet.

Virtuelle Adresse: Die durch segmentierte Speicherverwaltung zugeordnete Adresse wird als lineare Adresse oder auch als virtuelle Adresse bezeichnet

Physikalische Adresse: physikalische Speicheradresse

veranschaulichen:

Beim Inetel-Prozessor ist die logische Adresse die Adresse vor der Konvertierung „Segmentspeicherverwaltung“ und die lineare Adresse die Adresse vor der Konvertierung „Seitenspeicherverwaltung“.

Die durch die segmentierte Speicherverwaltung zugeordnete Adresse ist keine „physische Adresse“ mehr, Intel nennt sie eine „lineare Adresse“ (auch virtuelle Adresse genannt). Daher ordnet die segmentierte Speicherverwaltung zunächst logische Adressen linearen Adressen zu und anschließend ordnet die seitenweise Speicherverwaltung lineare Adressen physischen Adressen zu.

Der Linux-Speicher wird hauptsächlich durch den Seitenspeicher verwaltet, es sind jedoch auch Segmentierungsmechanismen beteiligt. Der derzeit vom Linux-Kernel verfolgte Ansatz besteht darin, den Segmentzuordnungsprozess praktisch wirkungslos zu machen.

Der erste Prozessor von Intel, der 80286, war rein segmentbasiert, während der 80386 sowohl über Segment- als auch über Seitenverwaltung verfügte.

2. Seitenverwaltung

32-Bit-CPU mit x86-Architektur

​ Adressierungsmethode der sekundären Seitentabelle, eine Speicherseite ist 4 KB groß, die Seitenverzeichnistabelle der ersten Ebene hat 1024 Einträge, die Seitentabelle der zweiten Ebene hat 1024 Einträge und ein Seitentabelleneintrag ist 4 Byte groß. Die Seitenverzeichnistabelleneinträge der ersten Ebene werden alle zugewiesen und die Seitentabelle der zweiten Ebene wird bei Bedarf erstellt. (Lokalitätsprinzip).

Virtuelle Adresse 32 Bit

10 + 10 + 12 indizieren jeweils die Seitentabellennummer der Ebene 1, den Seitentabelleneintrag der Ebene 2 und zeichnen die Offsetadresse der physischen Basisadresse auf. Nach Verwendung des PAE-Mechanismus beträgt der maximale Speicher, der von einem 32-Bit-System unterstützt wird, 64 GB (die Adresse ist 32 + 4 = 36 Bit).

Lineare Adressierung Adressierung physikalische Adressschritte

Verwenden Sie zunächst die 10-Bit-Adressierungsseitentabellennummer der Ebene 1. Die Seitentabellennummer der Ebene 1 zeichnet die Adresse der Seitentabelle der Ebene 2 auf.

Nachdem die Adresse der Seitentabelle der Ebene 2 ermittelt wurde, wird der Speicherort des Eintrags in der Seitentabelle der Ebene 2 anhand der anderen 10 Bits der virtuellen Adresse ermittelt.

Nachdem der Eintrag der Seitentabelle der Ebene 2 gefunden wurde, zeichnet der Eintrag die Startadresse der virtuellen Adresse auf, die der physischen Adresse zugeordnet ist. Die Größe des Eintrags beträgt 4 Byte (32 Bit).

Die endgültige physikalische Adresse wird basierend auf der Startadresse der gefundenen physikalischen Adresse berechnet, kombiniert mit den letzten 12 Bits der virtuellen Adresse als Offset

x86-Architektur 64-Bit-CPU

Es gibt mehr Ebenen von Seitentabellen

Globales Seitenverzeichnis PGD (Page Global Directory) Oberes Seitenverzeichnis PUD (Page Upper Directory) Mittleres Seitenverzeichnis PMD (Page Middle Directory) Seitentabelleneintrag PTE (Page Table Entry)

Lineare Adressierung Adressierung physikalische Adressschritte

Die lineare Adresse beträgt 48 Bit, die maximale physische Adresse 52 Bit und die tatsächliche physische Speicheradressbusbreite beträgt 40 Bit, was bedeutet, dass 1 TB physischer Speicher unterstützt wird. x86_64 verfügt über eine Seitentabelle mit vier Ebenen und das Prinzip ist dasselbe wie das des x86-Systems, das ebenfalls Schicht für Schicht adressiert wird. Das CR3-Register speichert die anfängliche physische Adresse der Tabelle der höchsten Ebene. Der erste Schritt bei der Adressierung besteht also darin, den Wert im CR3-Register abzurufen. Die Größe jedes PTE-Eintrags beträgt 8 Byte, also 64 Bit.

TLB

Im CPU-Chip wird ein Cache hinzugefügt, um die vom Programm am häufigsten aufgerufenen Seitentabelleneinträge zu speichern. Dieser Cache ist TL (Translation Lookaside Buffer). Er wird üblicherweise als Seitentabellen-Cache, Umleitungs-Bypass-Cache, Fast Table usw. bezeichnet. Wenn dann die Speicherverwaltungseinheit MMU der CPU nach einer Adresse sucht, überprüft sie zuerst den TLB. Wenn sie diese nicht findet, wird weiterhin die normale Seitentabelle überprüft.

Eigenname

PDT: Seitenverzeichnistabelle, mehrstufige Seitentabelle, Seitentabelle der ersten Ebene, 32-Bit-System hat 1024 Seitenverzeichnisse
PTT: Seitentabelleneinträge, mehrstufige Seitentabelle, sekundäre Seitentabelle, 32-Bit-System hat 1024 Seitentabelleneinträge unter jedem Seitenverzeichnis, jeder Eintrag ist 4 Bytes groß
PDE: Die Basisadresse der Seitentabelle, die ein Element in PDT ist
PTE: ist die Basisadresse der Seite, eine der PTT
GDT: Global Descriptor Table, wird verwendet, um logische Adressen in lineare Adressen umzuwandeln
LDT: Local Descriptor Table, wird verwendet, um logische Adressen in lineare Adressen umzuwandeln

3. Adressaufteilung

32 Systemkernel 1G: 0xC0 00 00 01 - 0xFF FF FF FF
Benutzer 3G: 0x00 00 00 00 - 0xC0 00 00 00
0xC0 00 00 00 == 3G

64-Bit-Systeme:
Kernel 128T: 0xFF FF 80 00 00 00 00 00 - 0xFF FF FF FF FF FF FF FF FF (hoch)
0xFF FF 7F FF FF FF FF FF FF - 0xFF FF FF FF FF FF FF FF FF (selbst berechnen)

Benutzer 128T: 0x00 00 00 00 00 00 00 00 - 0x00 00 7F FF FF FF FF FF (niedrigere Ordnung)
0x00 00 80 00 00 00 00 00 - 0x00 00 80 00 00 00 00 00 (selbst berechnen)

​ 0x00 00 7F FF FF FF FF FF == 127T
Frage: Ist 128T die Trennlinie für ein 64-Bit-System? Ist es 127T?

Zugriffsrechte

Wenn sich ein Prozess im Benutzermodus befindet, kann er nur auf den Benutzerspeicher zugreifen. Erst wenn er in den Kernelmodus wechselt, kann er auf den Kernelspeicher zugreifen.

PAE-Mechanismus

Die CPU-Bitbreite bezieht sich auf die Anzahl der Binärbits, die die CPU innerhalb eines Taktzyklus verarbeiten kann. In normalen Szenarien kann der Adressbus einer 32-Bit-System-CPU 32 Bit betragen. Nach der Einführung des PAE-Mechanismus kann die Adressbus-Bitbreite einer 16-Bit-CPU jedoch 20 Bit betragen (physischer Speicher 1 MB), die Adressbus-Bitbreite einer 32-Bit-CPU kann 36 Bit betragen (physischer Speicher 64 GB) und die Adressbus-Bitbreite einer 64-Bit-CPU kann 40 Bit betragen (physischer Speicher 1 TB). Daher kann nicht einfach gesagt werden, dass 32-Bit-Systeme nur Speichersticks mit einer maximalen Größe von 4 GB unterstützen.

4. Debuggen

Programmregister

cs: ist das Codesegmentregister
ds: ist das Datensegmentregister
ss: ist das Stapelsegmentregister
es: ist das erweiterte Segmentregister
fs: ist das Flag-Segmentregister nach 32 Bit
gs: ist das globale Segmentregister nach 32 Bit

Beispiel für ein Kernel-Absturzprotokoll:

RUHE IN FRIEDEN: 0010:[ ] [ ] xxxxxxxxxx+0x69/0x70
RSP: 0018:ffff886241737d98 EFLAGS: 00010246
RAX: ffff880034814d40 RBX: ffff881fc6248740 RCX: 0000000000000200
RDX: 0000000000000000 RSI: 000000000000286 RDI: ffff881fc6381858
RBP: ffff886241737d98 R08: ffff886241734000 R09: 0000000000000000
R10: ffff880034814d40 R11: 0000000000000200 R12: ffff881fc62487a0
R13: 0000000000000000 R14: 00007fff86cb6260 R15: ffff881fc6381858
FS: 00007f78b59b8720(0000) GS:ffff885ffe3c0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f690a057180 CR3: 0000006208985000 CR4: 00000000003627e0
DR0: 0000000000000000 DR1: 000000000000000 DR2: 000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400

Programmregister anzeigen

Verwenden Sie GDB, um eine ausführbare ELF32-Datei unter Linux 32-Bit zu debuggen, und verwenden Sie den Befehl info r, um den Registrierungsstatus zu überprüfen:

Es gibt zwei Fälle für Segmentregister: 0x23 und 0x2b:

Hexadezimal: 0023
Binär: 0000000000100 0 11 - Segmentnummer: 4 - Tabellentyp: GDT - Berechtigungsstufe: Ring3
Hexadezimal: 002B
Binär: 0000000000101 0 11 - Segmentnummer: 5 - Tabellentyp: GDT - Berechtigungsstufe: Ring3

Segmentnummer: beginnt beim vierten Bit Tabellentyp: das dritte Bit Berechtigungsstufe: das erste und zweite Bit

Ich konnte keinen Befehl oder kein Tool finden, um GDT direkt in Linux anzuzeigen. Deshalb habe ich mir den Quellcode angesehen, um die Antwort zu finden:

Sehen Sie, die von diesen beiden Elementen beschriebenen Segmente sind dieselben wie bei Windows, mit einer Basisadresse von 0 und einer Größe von 4 GB.

Sowohl Windows als auch Linux umgehen auf diese Weise den segmentierten Speicherverwaltungsmechanismus der CPU.

Es ist jedoch zu beachten, dass dies zwar bei beiden Betriebssystemen der Fall ist, dies jedoch nicht bedeutet, dass der Segmentierungsmechanismus vollständig ungenutzt bleibt. Das Task-Management-TSS der CPU muss weiterhin verwendet werden. Das muss jeder wissen. Der Segmentierungsmechanismus ist unter dem 64-Bit-Linux-System nicht willkommen, aber das Betriebssystem behält weiterhin die Adressierungsmethode „Erst segmentieren und dann paginieren“ bei.

Abschluss

Damit ist dieser Artikel über die Speicherverwaltung und -adressierung unter Linux abgeschlossen. Weitere Informationen zur Speicherverwaltung und -adressierung unter Linux finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung der Speicherverwaltungsarchitektur des Linux-Kernels
  • Detaillierte Analyse des Linux-Speicherverwaltungsmechanismus
  • Linux Administratorhandbuch (4) -- Speicherverwaltung

<<:  Detaillierte Erläuterung der Kommunikation zwischen Angular-Eltern- und -Kindkomponenten

>>:  Zusammenfassung der Erfahrungen mit der Entwicklung von HTML+CSS-Projekten (empfohlen)

Artikel empfehlen

Leistung des Node+Express-Testservers

Inhaltsverzeichnis 1 Testumgebung 1.1 Server-Hard...

Implementierung von 2D- und 3D-Transformationen in CSS3

CSS3 implementiert 2D-Ebenentransformation und vi...

So laden Sie das JAR-Paket über die Webseite auf Nexus hoch

Wie lädt man das JAR-Paket in ein privates Lager ...

Verwendung des Linux-Befehls ln

1. Befehlseinführung Mit dem Befehl ln werden Lin...

So stellen Sie verschiedene Mausformen dar

<a href = "http: //" style = "c...

Benutzererfahrung bei der Neugestaltung der Portal-Website

<br />Vom Start der neuen Homepage von NetEa...

So ändern Sie den MySQL-Zeichensatz utf8 in utf8mb4

Wenn für MySQL 5.5 der Zeichensatz nicht festgele...

Aufrufen und Ausführen von Host-Docker-Operationen im Docker-Container

Zunächst einmal ist dieser Beitrag Docker-Neuling...

Details zum Überschreiben von Prototypmethoden in JavaScript-Instanzobjekten

Inhaltsverzeichnis In JavaScript können wir norma...

Erläuterung der Konfiguration und Verwendung der MySQL-Speicher-Engine InnoDB

MyISAM und InnoDB sind die gängigsten Speicher-En...

So installieren Sie die Linux-Onlinesoftware gcc online

Befehle zur Linux-Onlineinstallation: yum install...