2012-03-28 3 views
2

Ich kam auf diese Frage, weil ich nicht verstehe, wie Adressumsetzung im Kernelbereich ausgeführt wird.Wie erfolgt die Adressumsetzung (virt-> phy), wenn die CPU eine Adresse über 0xC0000000 benötigt?

Von dem, was ich verstehe, jede Adresse über 0xC0000000 zu übersetzen, wir minus diese Adresse mit PAGE_OFFSET nur zu müssen (mit Ausnahme des Kernel-Initialisierungsprozess, wo wir eine Seitentabelle für 8MB Bereich benötigen). Dies ist jedoch nicht sinnvoll, wenn die CPU einen Befehl ausführt, der eine Adresse benötigt, beispielsweise 0xF0000020, während das System nur über 256 MB RAM verfügt.

Aus dem obigen Grund denke ich, dass der Kernel tatsächlich eine Seitentabelle hat, die es der MMU ermöglicht, die virtuelle Adresse über 0xC0000000 in physisch zu übersetzen. Also, in welcher Situation können wir direkt minus die PAGE_OFFSET und in welcher Situation brauchen wir die Kernel-Seitentabelle?

Ich kann am Anfang falsch, also bitte korrigieren.


EDIT

Von < < den Virtual Memory Manager Linux Legendes >>, wo es Kernel-Seitentabelle vorhanden ist, sagt. Jetzt, mehr verwirrt ...

3,6 Kernel Page Tables

Wenn das System zum ersten Mal gestartet wird, Paging ist nicht aktiviert, weil Seitentabellen nicht magisch selbst initialisieren. Jede Architektur implementiert dies anders, so dass nur der x86-Fall diskutiert wird. Die Initialisierung der Seitentabelle ist in zwei Phasen unterteilt: . Die Bootstrap-Phase richtet Seitentabellen für nur 8MB ein, so dass die Paging-Einheit aktiviert werden kann. Die zweite Phase initialisiert den Rest der Seitentabellen. Wir besprechen diese beiden Phasen in den folgenden Abschnitten mit .

3.6.1 Bootstrapping

...

3.6.2 Finalisierung

Die Funktion verantwortlich für die Seitentabellen Finalisierung wird paging_init() aufgerufen. Das Aufrufdiagramm für diese Funktion auf dem x86 ist in Abbildung 3.4 zu sehen. enter image description here

Die Funktion ruft zuerst pagetable_init() die Seitentabellen erforderlich zu initialisieren alle physischen Speicher in ZONE_DMA und ZONE_NORMAL zu verweisen. Denken Sie daran, dass hoher Speicher in ZONE_HIGHMEM nicht direkt referenziert werden kann und dass die Zuordnungen vorübergehend dafür eingerichtet werden. Für jeden vom Kernel verwendeten pgd t wird der Boot-Speicher allocator (siehe Kapitel 5) aufgerufen, um eine Seite für das PGD zuzuordnen, und das Bit PSE wird gesetzt, wenn es 4MiB-TLB-Einträge statt 4KB verwendet. Wenn das Bit PSE nicht unterstützt wird, wird für jede PMT eine Seite für PTEs zugeordnet.Wenn die CPU das PGE-Flag unterstützt, wird sie auch so eingestellt, dass der Seitentabelleneintrag global und für alle Prozesse sichtbar ist.

Als nächstes ruft pagetable_init() fixrange_init() auf, um die feste Adresse Space-Mappings am Ende des virtuellen Adressraums ab FIXADDR_START einzurichten. Diese Zuordnungen werden für Zwecke wie den lokalen erweiterten programmierbaren Interrupt-Controller (APIC) und die von kmap_atomic() benötigten atomischen Kmappings zwischen FIX_KMAP_BEGIN und FIX_KMAP_END verwendet. Schließlich ruft die Funktion fixrang_init() auf, um die Seitentabelleneinträge zu initialisieren, die für normale Hochspeicher- -Zuordnungen mit kmap() erforderlich sind.

Nach pagetable_init() zurückkehrt, sind die Seitentabellen für Kernelraum nun vollständig initialisiert, so dass die statische PGD (swapper_pg_dir) in das CR3-Register geladen so , dass die statische Tabelle nun von der Paging-Einheit benutzt wird.

Die nächste Aufgabe von paging_init() ist verantwortlich für den Aufruf von kmap_init() an initialisieren jedes der PTEs mit den PAGE_KERNEL Schutz Flags. Die letzte Aufgabe ist , um zone_sizes_init() aufzurufen, wodurch alle verwendeten Zonenstrukturen initialisiert werden.

Antwort

0

Obwohl die lineare Abbildung für den Menschen etwas Besonderes zu sein scheint, ist sie (in der Regel) keine besondere MMU-Konfiguration.

Also wie Sie gesagt haben, um die virtuelle Adresse von 3G zu 3G + 900MB zu übersetzen, können wir direkt minus diese Adressen mit PAGE_OFFSET. Bedeutet das, dass der Kernel keine Seitentabellen benötigt?

Es benötigt immer noch diese Tabellen, um diese spezifische (lineare) Zuordnung zu MMU zu erklären. Es gibt jedoch einige spezielle Fälle wie MIPS R3000.

Aber das macht keinen Sinn, in dem die CPU eine Anweisung, die an der Adresse ausführt, erfordert, sagen 0xF0000020

Ich würde fragen, ob es Sinn Anweisung an dieser Adresse in erster Linie zur Ausführung macht. Was ich meine, ist, dass auf System mit 256MBs von RAM Sie nicht einfach solche Anfrage treffen werden (zumindest angenommen, dass der Code nicht fehlerhaft ist).

Der für Sie verwirrende Punkt ist IMO: Wer ist für die Adressübersetzung verantwortlich? Die Antwort ist (wieder gewöhnlich) MMU, implementiert in Hardware. Die Seitentabellen sind also die Art, MMU zu sagen, wie es solche Übersetzungen machen soll - das ist keine Kernverantwortung. Der Kernel muss nur MMU konfigurieren.

Wie wird die Adressumsetzung (virt-> phy) durchgeführt, wenn die CPU eine Adresse über 0xC0000000 benötigt?

Genau wie für die Adressen unten. This Lesen kann hilfreich sein.

0

Es gibt eine lineare Abbildung für die ersten 900 MB an physikalischem Speicher (falls vorhanden), so dass die virtuelle Adresse für diesen Speicher auf den physikalischen Speicher gleich plus PAGE_OFFSET. Natürlich verhindert dies nicht, dass derselbe physische Speicher an anderer Stelle im Adressraum eines Prozesses abgebildet wird, sollte der Kernel diesen Speicher für andere Zwecke verwenden wollen.

+0

Also wie Sie gesagt haben, um die virtuelle Adresse von 3G zu 3G + 900MB zu übersetzen, können wir direkt diese Adressen mit PAGE_OFFSET abzüglich. Bedeutet das, dass der Kernel keine Seitentabellen benötigt? Aber es existiert tatsächlich, deshalb verstehe ich nicht, was die Kernelseitentabelle abdeckt. Bitte beachten Sie die EDIT. – sliter

+0

Alles benötigt Seitentabellen im linearen Modus; Diese Zuordnung ist nur eine Konvention, die den Zugriff auf die ersten 900 MB physischen Speicher erleichtert. – Neil

0

In der Tat verwendet Ihr Userspace-Programm oder sogar Kernel die virtuelle Adressierung. Dies bedeutet, dass jede Speicheranforderung MMU durchläuft. Wenn es durch MMU geht verwendet es Seitentabellen (CR3-Register auf x86 sehen)

virtual addr --> MMU --> physical addr 

Und Kernel nicht einige magische Optimierung nicht verwenden, wenn Sie lowmem zugreifen. Ja lowmem wird direkt abgebildet, deshalb können Sie aus menschlicher Sicht virtuelle Adressen von niedrig zu physikalisch durch eine einfache Subtraktion übersetzen, aber die CPU führt diese Übersetzung durch Kernel-Seitentabellen aus.