Heim > Artikel > Betrieb und Instandhaltung > Speicherverwaltung im geschützten Linux-Modus
Wir wissen, dass der Speicher als ein sehr großes Array betrachtet werden kann. Wenn wir ein Element im Speicher finden möchten, wird es durch den Index des Arrays angegeben. Das Gleiche gilt für den Speicher, aber es gibt eine Voraussetzung Das Array besteht aus einer Reihe geordneter Bytes. In diesem geordneten Byte-Array hat jedes Byte eine eindeutige Adresse. Diese Adresse wird auch als Speicheradresse bezeichnet.
Im Speicher sind viele Objekte gespeichert, z. B. ein char-Objekt, ein byte-Objekt, ein int-Objekt usw. Die CPU ist in verschiedene Speicherorte unterteilt Der Vorgang des Auffindens der Adressen dieser Objekte wird als Speicheradressierung bezeichnet. Die Speicherbusbreite bestimmt, wie viele Bits der Speicheradresse ab Adresse 0 adressiert werden können. Da 80X86 32 Bit ist, beträgt die Busbreite auch 32 Bit, sodass insgesamt 2 ^ 32 Speicheradressen vorhanden sind, sodass insgesamt 4 GB Speicheradressen gespeichert werden können. Mehrere Byte-Datentypen wie int, long und double können über aufeinanderfolgende Speicheradressen extrahiert werden.
Obwohl Objekte adressiert werden können, ist die Bytereihenfolge, in der diese Objekte gespeichert werden, unterschiedlich. Es gibt zwei Speichermethoden, nämlich Big Endian und Little Endian.
Zum Beispiel gibt es ein Objekt vom Typ int an der Adresse 0x100 und sein Hexadezimalwert ist 0x01234567. Ich werde Ihnen ein Bild zeichnen und Sie werden den Unterschied zwischen den beiden Speicherreihenfolgen verstehen.
Das ist eigentlich leicht zu verstehen. Der int-Datentyp von 0x01234567 kann in 01 23 45 67 Bytes aufgeteilt werden, und 01 ist das High-Bit und 67 das Low-Bit, also die Speicherreihenfolge von Little Endian Big-Endian-Methoden können erklärt werden: Das heißt, die Little-Endian-Methode verwendet zuerst das Bit niedriger Ordnung, während die Big-Endian-Methode zuerst das Bit hoher Ordnung verwendet. Der Unterschied zwischen Big-Endian und Little-Endian besteht nur in der Speicherreihenfolge und hat nichts mit der Anzahl der Ziffern und dem numerischen Wert des Objekts zu tun. Die meisten Intel-Maschinen verwenden den Little-Endian-Modus, daher ist 80X86 auch Little-Endian-Speicher, während die meisten IBM- und Oracle-Maschinen Big-Endian-Speicher verwenden.
Da der Computer nicht alle Daten im Speicher auf einmal ansprechen kann, weil dieser relativ groß ist, wird der Speicher im Allgemeinen segmentiert. Dabei stellt sich die Frage: Warum ist der Speicher segmentiert? Ich habe oben nur eine allgemeine Einführung gegeben.
Warum muss das Gedächtnis segmentiert werden?
https://www.php.cn/link/d005ce7aeef46bd18515f783fb8e87fa
Mit dem Segmentierungsmechanismus wird der Speicherplatz in lineare Bereiche unterteilt, und jeder lineare Bereich kann anhand der Segmentbasisadresse plus dem Intrasegment lokalisiert werden versetzt. Der Basisadressteil des Segments wird durch einen 16-Bit-Segmentselektor angegeben, von dem 14 Bits 2^14, also 16384 Segmente, auswählen können. Der Offset-Adressteil innerhalb des Segments wird mithilfe eines 32-Bit-Werts angegeben Die Adresse innerhalb des Segments kann zwischen 0 und 4 GB liegen. Die maximale Länge eines Segments beträgt 4 GB, was der oben erwähnten Speicheradresse von 4 GB entspricht. Eine 48-Bit-Adresse oder ein langer Zeiger, der aus einem 16-Bit-Segment und einem Offset innerhalb eines 32-Bit-Segments besteht, wird als logische Adresse bezeichnet, und die logische Adresse ist die virtuelle Adresse.
In der X86-Architektur gibt es sechs spezielle Register zum Speichern von Segmentbasisadressen: CS, DS, ES, SS, FS und GS. CS wird zur Adressierung des Codesegments, SS zur Adressierung des Stapelsegments und andere Register zur Adressierung des Datensegments verwendet. Das vom CS zu einem bestimmten Zeitpunkt adressierte Segment wird als aktuelles Codesegment bezeichnet. Die Offset-Adresse des nächsten Befehls, der im aktuellen Codesegment ausgeführt werden soll, ist bereits im EIP-Register vorhanden. Zu diesem Zeitpunkt kann die Segmentbasisadresse:Offsetadresse als CS:EIP ausgedrückt werden.
Das vom Segmentregister SS adressierte Segment wird als aktuelles Stapelsegment bezeichnet. SS:ESP zeigt jederzeit auf die Spitze des Stapels, und es gibt keine Ausnahmen Die anderen vier sind allgemeine Datensegmentregister. Wenn der Befehl standardmäßig kein Datensegment enthält, wird es von DS angegeben.
Normalerweise besteht ein vollständiges Speicherverwaltungssystem aus zwei Komponenten: Zugriffsschutz und Adressübersetzung. Der Zugriffsschutz soll verhindern, dass eine Anwendung auf eine Speicheradresse zugreift, die von einem anderen Programm verwendet wird. Die Adressübersetzung dient dazu, eine dynamische Adresszuweisungsmethode für verschiedene Anwendungen bereitzustellen. Zugriffsschutz und Adressübersetzung ergänzen sich.
Bei der Adressübersetzung werden normalerweise Speicherblöcke als Grundeinheit verwendet. Hier finden Sie eine Erklärung, was ein Block ist. Wie wir alle wissen, sind in Linux alles Dateien, die aus Blöcken bestehen. Die Komponenteneinheit des Systems ist auch die Grundeinheit der Datenverarbeitung. Gängige Blöcke haben unterschiedliche Größen, z. B. 512 B, 1 KB, 4 KB usw. Obwohl ein Block die Grundeinheit ist, besteht er im Wesentlichen aus Sektoren.
Es gibt zwei Möglichkeiten, die Adressübersetzung zu implementieren: den Segmentierungsmechanismus und den Paging-Mechanismus. Die Implementierung der Speicherverwaltung in x86 kombiniert Segmentierungs- und Paging-Mechanismen. Das Folgende ist ein Zuordnungsdiagramm virtueller Adressen, die nach Segmentierung und Paging in physische Adressen umgewandelt werden
Für dieses Bild ist Folgendes zu erklären:
Zunächst enthält dieses Bild drei Adressen und den Konvertierungsprozess dieser drei Adressen. Nach der segmentierten Basisadresskonvertierung wird die lineare Adresse zur Segmentbasisadresse + Intra-. Segmentoffset, daher ist dieses Bild ein Adressübersetzungsdiagramm im geschützten Modus. Die lineare Adresse wird nach dem Paging-Mechanismus in eine physische Adresse umgewandelt, sofern der Paging-Mechanismus aktiviert werden muss. Wenn der Paging-Mechanismus nicht aktiviert ist, ist die lineare Adresse = physische Adresse.
Ich muss noch einmal über die logische Adresse sprechen. Die logische Adresse enthält den Segmentselektor und den Intra-Segment-Offset. Das Konzept des Segmentselektors war relativ vage, als ich damit in Kontakt kam Wir alle wissen, dass die Segmentbasisadresse im geschützten Modus 16 Bit und der Offset innerhalb des Segments 32 Bit beträgt.
In vielen Büchern oder Artikeln werden Segmentselektoren erwähnt. Im Englischen handelt es sich ausschließlich um Segmentselektoren.
Segmentdeskriptor wird später erwähnt. Segmentdeskriptor und Segmentselektor sind nicht dasselbe, aber der Segmentselektor ist ein 16-Bit-Segmentdeskriptor.
Lassen Sie mich Ihnen etwas sagen, das in diesem Bild nicht steht. Jetzt weiß jeder, dass logische Adressen in lineare Adressen und lineare Adressen in physische Adressen umgewandelt werden können. Tatsächlich wird hier die MMU (Speicherverwaltungseinheit) zur Konvertierung verwendet, und die Konvertierung linearer Adressen in physische Adressen verwendet die Hardwareschaltung der Paging-Einheit. Der Schwerpunkt dieses Artikels liegt nicht auf der Erörterung des spezifischen Konvertierungsprozesses, sondern auf den beiden Mechanismen Segmentierung und Paging.
Lassen Sie uns im Detail über die beiden Mechanismen Segmentierung und Paging sprechen.
Ich empfehle Ihnen, zuerst die Beschreibung zu lesen, die ich zum Thema „Warum Speicher segmentiert werden muss“ geschrieben habe.
https://www.php.cn/link/d005ce7aeef46bd18515f783fb8e87fa
Mehrere Programme werden im selben Speicherbereich ausgeführt und stören sich nicht gegenseitig. Dies liegt daran, dass die Segmentierung für die Isolierung von Code-, Daten- und Stapelbereichen sorgt . Wenn in der CPU mehrere Programme oder Aufgaben ausgeführt werden, kann jedem Programm ein eigener Satz von Segmenten zugewiesen werden (einschließlich Programmcode, Daten und Stapel). Die CPU verhindert, dass Anwendungen sich gegenseitig stören, indem sie die Grenzen zwischen den Segmenten stärkt.
Alle in einem System verwendeten Segmente sind im linearen Adressraum der CPU enthalten. Um ein Byte in einem bestimmten Segment zu finden, muss das Programm eine logische Adresse bereitstellen, damit die Übersetzung stattfinden kann. Die logische Adresse enthält den Segmentselektor und den Offset innerhalb des Segments. Jedes Segment verfügt über einen Segmentdeskriptor. Der Segmentdeskriptor wird verwendet, um die Größe des Segments, die Zugriffsrechte und die Berechtigungsstufe des Segments, den Segmenttyp und das erste Byte anzugeben des Segments ist der Online-Standort im sexuellen Adressraum (Segment-Basisadresse). Der Offset-Teil der logischen Adresse wird zur Segmentbasisadresse hinzugefügt, um die Position eines bestimmten Bytes im Segment zu lokalisieren, sodass die Segmentbasisadresse + Offset die Adresse im linearen Adressraum der CPU bildet.
Der lineare Adressraum hat die gleiche Struktur wie der physische Adressraum, aber die Segmente, die er aufnehmen kann, sind sehr unterschiedlich. Die virtuelle Adresse, d. h. der logische Adressraum, kann bis zu 16 K-Segmente enthalten, und jedes Segment kann eine Größe von 4 GB, sodass die virtuelle Adresse insgesamt 64 TB (2 ^ 46) Segmente finden kann und der lineare Adress- und physische Adressraum 4 GB (2 ^ 32) beträgt. Wenn also Paging deaktiviert ist, ist der lineare Adressraum der physische Adressraum.
Dieses Bild ist das Zuordnungsdiagramm der logischen Adresse – > lineare Adresse – > Die GDT-Tabelle und die LDT-Tabelle belegen jeweils die Hälfte des Adressraums mit jeweils 8192 Segmenten bis 4 G, ob aus der GDT-Tabelle oder der LDT-Tabelle abgefragt werden soll, welche Tabelle abgefragt werden soll, hängt vom TI-Attribut des Segmentselektors ab. Die Struktur des Segmentselektors ist wie folgt:
Der Segmentselektor ist unterteilt in Insgesamt drei Teile:
Hier gibt es keine detaillierte Erklärung der Segmentdeskriptoren, da dieser Artikel immer noch die Speicherverwaltung bevorzugt und sich nicht zu sehr auf bestimmte Details konzentriert.
In GDTR kann die logische Adresse, bestehend aus Segmentselektor und Offset, zu einem Segmentdeskriptor synthetisiert und direkt gespeichert werden. Segmentselektoren und Intrasegment-Offsets können nach dem Durchlaufen der MMU in lineare Adressen umgewandelt werden.
Wie oben erwähnt, wird die lineare Adresse von der logischen Adresse umgewandelt. Wenn der Paging-Mechanismus aktiviert ist, ist die lineare Adresse die Anzahl der linearen Adressen Adressräume sind immer noch unterschiedlich. Im Allgemeinen sind Programme Multitasking-fähig, und der lineare Adressraum, der normalerweise durch Multitasking definiert wird, ist viel größer als die physische Speicherkapazität. Warum? Die Adressübersetzungskarte zeigt, dass sowohl die lineare Adresse als auch die physische Adresse 4G groß sind. Das liegt daran, dass lineare Adressen durch virtuelle Speichertechnologie virtualisiert werden.
Virtueller Speicher ist eine Speicherverwaltungstechnologie, die uns die Illusion vermitteln kann, dass der Speicherplatz viel größer ist als die tatsächliche physische Speicherkapazität. Das bedeutet, dass der Speicher möglicherweise nur 4G groß ist. Aber Sie denken, der Speicher hat 64 G, deshalb kann ich so viele Anwendungen öffnen.
Der Paging-Mechanismus ist eigentlich eine Implementierung der Virtualisierung. In einer virtualisierten Umgebung wird ein großer Teil des linearen Adressraums einem kleinen Teil des physischen Speichers (RAM oder ROM) zugeordnet. Beim Paging wird jedes Segment in Seiten (normalerweise 4 KB) unterteilt und diese Seiten werden im physischen Speicher oder auf der Festplatte gespeichert. Das Betriebssystem verwaltet diese Seiten mithilfe eines Seitenverzeichnisses und von Seitentabellen. Wenn ein Programm versucht, auf eine Adressposition im linearen Adressraum zuzugreifen, verwendet die CPU das Seitenverzeichnis und die Seitentabelle, um die lineare Adresse in eine physische Adresse umzuwandeln und sie dann im physischen Speicher zu speichern.
Wenn sich die aktuell aufgerufene Seite nicht im physischen Speicher befindet, führt die CPU einen Interrupt aus. Der allgemeine Fehler ist eine Seitenausnahme. Anschließend liest das Betriebssystem die Seite von der Festplatte in den physischen Speicher und führt sie dann weiter aus Programm ab der Unterbrechungsstelle. Das Betriebssystem tauscht häufig Seiten ein und aus, was ebenfalls zu einem Leistungsengpass führt.
Bei der Segmentierung ist die Länge jedes Segments nicht festgelegt und die maximale Länge beträgt 4G, während beim Paging die Größe jeder Seite festgelegt ist. Ob im physischen Speicher oder auf der Festplatte, die Verwendung von Seiten mit fester Größe eignet sich besser für die Verwaltung des physischen Speichers, während der Segmentierungsmechanismus mit Blöcken variabler Größe besser für die Verarbeitung logischer Partitionen komplexer Systeme geeignet ist.
Obwohl Segmentierung und Paging zwei verschiedene Adressübersetzungsmechanismen sind, werden sie während des gesamten Adressübersetzungsprozesses unabhängig voneinander behandelt, und jeder Prozess ist unabhängig. Beide Mechanismen verwenden eine Zwischentabelle zum Speichern von Eintragszuordnungen, die Struktur dieser Zwischentabelle ist jedoch unterschiedlich. Die Segmenttabelle existiert im linearen Adressraum und die Seitentabelle wird im physischen Adressraum gespeichert.
80x86 verfügt über zwei Schutzmechanismen, von denen einer eine vollständige Isolierung zwischen Aufgaben erreicht, indem jeder Aufgabe unterschiedliche virtuelle Adressräume zugewiesen werden. Dies wird erreicht, indem jeder Aufgabe eine andere Umwandlung von einer logischen Adresse in eine physische Adresse zugewiesen wird. Jede Anwendung kann nur auf Daten und Anweisungen in ihrem eigenen virtuellen Raum zugreifen und die physische Adresse nur über ihre eigene Zuordnung erhalten. Schützen Sie die Speichersegmente des Betriebssystems und einige spezielle Register vor dem Zugriff durch Anwendungen. Lassen Sie uns diese beiden Aufgaben im Folgenden im Detail besprechen.
Jede Aufgabe wird separat in ihrem eigenen virtuellen Adressraum platziert und dann über die Hardware einer physischen Adresse zugeordnet. Verschiedene virtuelle Adressen werden in unterschiedliche physische Adressen umgewandelt, und es gibt keine virtuelle Adresse von A Die Adresse wird dem Bereich der physischen Adresse zugeordnet, an der sich B befindet, sodass alle Aufgaben isoliert sind und sich verschiedene Aufgaben nicht gegenseitig stören.
Jede Aufgabe verfügt über eine eigene Zuordnungstabelle, Segmenttabelle und Seitentabelle. Wenn die CPU zwischen verschiedenen Anwendungen oder Aufgaben wechselt, wechseln auch diese Tabellen.
Virtuelle Adresse ist eine Abstraktion des Betriebssystems, was bedeutet, dass die virtuelle Adresse vollständig vom Betriebssystem als Träger abstrahiert wird, der Anwendungen und Aufgaben besser verwalten kann zeigt, dass jede Aufgabe Zugriff auf das Betriebssystem hat, das von allen Aufgaben gemeinsam genutzt wird. Dieser Teil des virtuellen Adressraums, in dem alle Aufgaben denselben virtuellen Adressraum haben, wird als globaler Adressraum bezeichnet, und Linux verwendet den globalen Adressraum.
Jede Aufgabe im globalen Adressraum verfügt über einen eigenen, einzigartigen virtuellen Adressraum. Dieser virtuelle Adressraum wird als lokaler Adressraum bezeichnet.
Wenn der Schutz des Betriebssystems zwischen verschiedenen Aufgaben mit einem horizontalen Schutz verglichen wird, kann der Schutz von Speichersegmenten und Registern als vertikaler Schutz angesehen werden. Um den Zugriff auf verschiedene Segmente innerhalb einer Aufgabe einzuschränken, legt das Betriebssystem vier Berechtigungsstufen fest, um jede Aufgabe zu schützen.
Die Priorität ist in 4 Stufen unterteilt, 0 ist die höchste und 3 die niedrigste. Im Allgemeinen erhalten die vertraulichsten Daten die höchste Priorität, und auf sie kann nur der vertrauenswürdigste Teil der Aufgabe zugreifen. Weniger vertrauliche Daten erhalten im Allgemeinen eine niedrigere Priorität, Anwendungsdaten dagegen im Allgemeinen Level 3. Jedem Speichersegment ist eine Berechtigungsstufe zugeordnet.
Wir wissen, dass die CPU über CS Anweisungen und Daten zur Ausführung erhält. Der Zugriff auf die vom Segment erhaltenen Anweisungen und Daten erfolgt im Allgemeinen mit der aktuellen Berechtigungsstufe (aktuelle Berechtigungsstufe). Ebene des aktuell aktiven Codes. Wenn eine Anwendung versucht, auf ein Segment zuzugreifen, wird es mit dieser Berechtigungsstufe verglichen und es kann nur auf Berechtigungsstufen zugegriffen werden, die niedriger als dieses Segment sind.
Das obige ist der detaillierte Inhalt vonSpeicherverwaltung im geschützten Linux-Modus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!