2016-03-28 5 views
7

Ich versuche, den Mechanismus in Linux der Zuordnung Kernel-Modus-Raum in Benutzermodus Raum mit mmap zu verstehen.Wie ist die Anatomie des Speicherabbilds Kernel-Raum

Zuerst habe ich ein ladbares Kernel-Modul (LKM), das ein Zeichengerät mit mmap-Funktionalität zur Verfügung stellt. Dann öffnet eine User-Space-Anwendung das Gerät und ruft mmap auf, wobei der LKM Speicherplatz im Heap des LKM innerhalb des Kernel-Mode-Space (virtuelle High-Adresse) reserviert. Auf der Benutzerraumseite zeigt der Datenzeiger auf eine virtuelle niedrige Adresse.

Das folgende Bild zeigt, wie ich mir die Anatomie der Erinnerung vorstelle. Ist das richtig?

Memory mapping

Bitte lassen Sie mich wissen, ob Frage nicht klar ist, ich werde versuchen, weitere Informationen hinzuzufügen.


Bearbeiten: Das Bild wurde in Bezug auf Gil Hamilton bearbeitet. Der schwarze Pfeil zeigt nun auf eine physikalische Adresse.

+2

Ja. Das ist grundsätzlich richtig. Ich würde es mit dem schweren schwarzen Pfeil nach rechts zeichnen. Das heißt, es teilt die gleichen physischen Seiten. Es erhält nicht die gleiche virtuelle Adresse wie der Kernel und es zeigt nicht irgendwie auf den Kerneldatenbereich. Stattdessen erhält es seine eigene unabhängige Zuordnung zu den gleichen physischen Speicherseiten. –

+0

Oft kann ich lesen, dass jeder Thread in Linux einen eigenen virtuellen Speicherbereich erhält, der in einen 1-GB-Kernel und einen 3-GB-Benutzerbereich aufgeteilt ist. In diesem Fall: Liegen einige Teile des Kernel-Moduls im Kernel-Space-Teil der User-Space-Anwendung? – Alex44

+1

Ja. In diesem Modell ist der virtuelle Adressraum des Kernels die oberste 1 GB (für x86 32bit). Der Benutzermodusraum ist die unteren 3 GB. Sie teilen also den virtuellen 4-GB-Adressraum. Wenn ein Kontextwechsel stattfindet, wird eine neue Seitentabelle installiert. Es hat dieselben Zuordnungen für die oberen 1GB, aber neue Zuordnungen für den Benutzermodus des neuen Prozesses. Der Benutzermodus kann jedoch niemals auf die oberste 1 GB zugreifen (d. H. Wenn er versucht, auf diesen Speicher zuzugreifen, wird er aufgrund von Zugriffsbeschränkungen für Seitentabellen einen "SIGSEGV" erhalten.) Der Kernel-Modus * kann technisch direkt auf den Benutzermodus zugreifen, obwohl dies in der Regel über eine API erfolgt. –

Antwort

0

Der Zeichnung fehlen einige wichtige zugrunde liegende Annahmen.

Der Kernel muss nicht mmap() Zugriff auf Benutzer Speicherplatz. Wenn ein Benutzerprozess über den Speicher verfügt, ist er bereits per Definition im Adressraum zugeordnet. In diesem Sinne ist der Speicher bereits zwischen Benutzer und Kernel aufgeteilt.

mmap() erstellt eine neue Region im virtuellen Adressraum des Benutzers, sodass der Adressbereich bei späterem Zugriff durch physischen Speicher gefüllt werden kann. Die tatsächliche Zuweisung von Speicher und die Änderung des Seitentabelleneintrags erfolgt durch den Kernel.

mmap() ist nur sinnvoll für die Verwaltung der Benutzerhälfte des virtuellen Adressraums. Kernel-Hälfte des Adressraums wird komplett anders verwaltet.

Auch die Kernel-Hälfte wird von allen Prozessen im System geteilt. Jeder Prozess hat seinen eigenen virtuellen Adressraum, aber die Seitentabellen sind so programmiert, dass die Seitentabelleneinträge für die Kernel-Hälfte für alle Prozesse genau gleich eingestellt sind.

Erneut greift der Kernel nicht auf mmap(), um auf Benutzerspeicher zuzugreifen. mmap() ist eher ein Service, den der Kernel dem Benutzer zur Verfügung stellt, um die aktuelle Abbildung im virtuellen Adressraum des Benutzers zu ändern.

BTW, der Kernel hat tatsächlich ein paar Möglichkeiten, auf Benutzerspeicher zugreifen, wenn es will.

Zuallererst hat der Kernel eine dedizierte Region des Kernadressraumes (als Teil seines Kernraumes), der die Gesamtheit des physikalischen Speichers, der in fortlaufender Weise vorhanden ist, abbildet. (Dies gilt für das gesamte 64-Bit-System. Im 32-Bit-System muss der Kernel "on-the-fly" neu zuordnen.)

Zweitens, wenn der Kernel über einen Systemaufruf oder eine Ausnahme aufgerufen wird Sie haben keinen gültigen Prozesskontext, so dass der Kernel den User Space Pointer direkt "dereferenzieren" kann, um den korrekten Wert zu erhalten. Wenn der Kernel drittens einen Benutzerraumzeiger eines Prozesses während der Ausführung in einem ausgeliehenen Kontext wie in einem Interrupt-Handler abstufen möchte, kann der Kernel die virtuelle Adresse des Prozesses verfolgen, indem er den Baum vm_area_struct zur Erlaubnis durchläuft und die Seitentabelle durchläuft finde den tatsächlichen physischen Seitenrahmen heraus.

0

Sie können die Speicherbereiche überprüfen, indem Sie durch vmas "struct vm_area_struct" durch den aktuellen Wert iterieren.

Wenn Sie Seitentabellen führen und abgeleitete physische Adressen für virtuelle Adressen ableiten, die nicht mit Benutzerbereich zusammenhängen, wird das Speicherlayout klarer.

Abgesehen von dieser kleinen Korrektur in dieser Figur ist BSS kein Segment, sondern Abschnitt, der zu Datensegment einzubetten ist, um weitere Informationen zu ELF-Spezifikation beziehen, Linker-Skript

Verwandte Themen