Christian Seiler: Speichermanagement, Ringe

Beitrag lesen

Hallo,

Was ich wohl verstanden habe ist das zuweisen von virtuellen Adressen, dahinter stehen echte Physikalische Adressen, ich hoffe das habe ich begriffen.
Doch ab wann werden die festgelegt, vom OS oder von der Hardware selbst?

In der Regel vom Betriebssystem. Das sagt dem Prozessor an Hand der sog. Page Table, welche virtuelle Adresse zu welcher physikalischen Adresse gehört. Das ganze geht aber noch weiter: Page Tables sind nicht eindeutig - jedes Programm hat einen eigenen Satz, sieht also seinen eigenen virtuellen Speicher. Wenn also das Programm geschaltet wird, wird die Page Table vom Betriebssystem ausgetauscht. Deswegen sind sog. "Kontextwechsel" beim Umschalten des Programms durch den Systemkern relativ teuer. (Zum Beispiel muss auf x86 der sog. TLB - Transaction Lookaside Buffer - gelöscht werden, der ist im Prozessor eine Art Zwischenspeicher für die Page Table, der extrem schnelles Lookup für die echten Adressen ermöglicht.)

Kennst selbst das OS die echten Adressen nicht und arbeitet nur auf virtuellen?

Das OS kennt zwar im Prinzip über die Page Table die physikalischen Adressen, aber außerhalb der Speicherverwaltung kümmert sich der Systemkern nie darum. Fast alles im Systemkern, was nicht mit Speicherverwaltung zu tun hat, arbeitet daher letztlich auch mit virtuellen Adressen. Dort will man ja letztlich auch die Vorteile von virtuellem Speicher nutzen können.

Und was wiederum hat das alles mit den Ringen zutun? Ring 0 kernel, Ring 1-3 Userspace. Kapiere das nicht..

Ein "Ring" ist eine Berechtigungsebene innerhalb des Prozessors, die einem Stück Code, das gerade ausgeführt wird, zugewiesen ist. Ring 0 darf alles, Ring 1 nur das, was Ring 0 ihm erlaubt, etc. Damit zieht ein abstürzendes Programm z.B. nicht das ganze Betriebssystem mit runter.

und warum muss ein OS im obersten Speicherbereich liegen?

Nein, das ist historisch so gewachsen - zumindest bei Linux. Wie's bei Windows aussieht weiß ich nicht, bei Mac OS X ist das ganze sogar ganz anders gelöst: Da liegen in den obersten paar Kilobyte (!) des Speichers die nötigen Routinen zur Speicherverwaltung + zum Umschalten von Prozessen und der Rest des Systemkerns ist ein eigenständiger Prozess. Das führt bei Mac OS X dazu, dass ein Systemaufruf aus einem Programm einen Kontextwechsel bewirkt (d.h. die Page Table ausgetauscht wird), unter Linux dagegen nicht. (Dafür hat die Mac OS X Variante den Vorteil, dass der Kernel und alle Treiber auf einem 64bit-System effektiv 32bit sein können und nur die Speicherverwaltung 64 bit können muss - womit man für Intel-Macs keine unterschiedlichen Treiber braucht für 32bit/64bit-Systeme und auf 64bit-Systemen dennoch native 64bit-Programme laufen lassen kann. Wenn dich näheres interessiert, empfehle ich diesen Vortrag.)

Und warum funktionieren nur dann Interrupts wenn ein Prozess einen fehler hat?

Nein. Ein Interrupt ist lediglich ein Ereignis, bei dem der Prozessor die aktuelle Ausführung von Code unterbricht und ein anderes Stück Code (den sog. "Interrupt Handler") ausführt (der potentiell mit anderen Rechten ausgetstattet ist). Interrupts können durch Fehler generiert werden (z.B. wird bei Division durch 0 häufig ein Interrupt erzeugt) - viel häufiger werden Interrupts aber gewollt erzeugt - entweder von Hardware, wenn diese etwas Kommunizieren will, oder von Software - unter Linux sorgt z.B. der Interrupt 0x80, dass der Kernel einen Systemaufruf ausführt - der "Interrupt Handler", den der Linux-Kernel für Int 0x80 installiert hat ist eine Funktion, die sich aus dem aktuellen Zustand des Programms - genauer gesagt den Inhalten der Register im Prozessor - heraussucht, welcher Systemaufruf ausgeführt werden soll und ruft dann die zugehörige Kernel-Funktion auf.

Weiteres Beispiel für die Nutzung von Interrupts: Wenn man Pages des virtuellen Speichers nicht im realen Speicher vorhält, sondern auf die Platte auslagert ("swapping"). Wenn ein Programm nun einen Speicherbereich auslesen oder beschreiben will, der gerade nicht im realen RAM vorrätig ist, dann ist der Page-Table-Eintrag so konstruiert, dass der Prozessor darüber stoplert, wenn der den Zugriff ermöglichen wird. Dies führt dann zu einer sog. "Page Fault Exception", welches dann den zugehörigen Interrupt Handler des Kernels ausführt. Der schaut dann nach, ob die Page auf der Platte ist und lädt die wieder in den Speicher. Oder, falls die Page z.B. nicht existiert, lässt der das Programm dann abbrechen, weil es auf einen ungültigen Speicherbereich zugreifen wollte. ("Segmentation Fault" unter Linux, "General Protection Fault" unter Windows.)

Viele Grüße,
Christian