2010-03-19 9 views
23

CPU Wechsel vom Benutzermodus zum Kernelmodus: Was genau macht es? Wie macht es diesen Übergang?CPU Wechselt vom Benutzermodus zum Kernelmodus: Was genau macht es? Wie macht es diesen Übergang?

EDIT:

Auch wenn es Architektur abhängig ist mir bitte eine Antwort geben. Die Architektur liegt bei Ihnen. Erzähl mir von der Architektur, die du kennst.

Ich möchte eine Vorstellung davon bekommen, was alles daran beteiligt sein wird.

+1

Es ist architekturabhängig und nicht unbedingt vom Betriebssystem abhängig. –

Antwort

28

Hinweis: Dies ist hauptsächlich für die x86-Architektur relevant. Hier ist eine etwas vereinfachte Erklärung.

Der Übergang in der Regel durch einen der folgenden Schritte verursacht:

  • Fehler (zB ein Seitenfehler oder eine andere Ausnahme verursacht durch die Ausführung eines Befehls)
  • Interrupt (beispielsweise ein Tastatur-Interrupt oder I/O Schlichten)
  • Trap (zB ein Systemaufruf)

Was normalerweise passiert, ist, dass das System überprüft die Interrupt Descriptor Table (IDT). Jeder Ausnahme (Interrupt, Fehler usw.) ist eine Nummer zugeordnet, die zum Indexieren in diese Tabelle verwendet wird.

Aus dieser Tabelle kann die CPU den auszuführenden Interrupt-Handler ermitteln.

Als Teil des Übergangs folgende Änderungen (in der Regel) wirksam:

  • Umschalten auf Kernel
  • EFLAGS Stapel
  • -Code Segmentselektor und EIP werden gespeichert, gespeichert.
  • Stapel Segmentselektor und Stapelzeiger
  • Beginn der Ausführung des Interrupt-Handlers
  • Die Universalregister gespeichert werden (handler Job)
  • Segmentselektoren werden geändert, um Kernel Einsen (handler Job)
gespeichert werden

Sie befinden sich jetzt im Kernel-Modus.

Hoffnung, das hilft :)

+1

Sind Interrupts während der Ausführung eines Interrupt-Handlers deaktiviert? Oder dürfen Interrupts höherer Priorität den bereits laufenden Interrupt-Handler unterbrechen? Kann es während der Ausführung eines Interrupt-Handlers einen Kontextwechsel geben? –

+0

Nur um zu verdeutlichen: Meinst du "Betriebssystem", wenn Sie schreiben "System überprüft die Interrupt-Deskriptor-Tabelle"? –

+0

@MartinThoma, ja, es ist OS-Code, der jetzt funktioniert. – fante

4

Das ist systemabhängig, aber der übliche Mechanismus ist eine Benutzerland-Operation verursacht einen Software-Interrupt. Dieser Interrupt veranlaßt den Prozessor, die Modi zu wechseln und in den Kernel-Code zu springen, der dann prüft, was das Programm zu tun versucht (Systemaufruf?), Und dann die angeforderte Aktion ausführt und zu dem Benutzermoduscode zurückspringt. Andere Mechanismen außer einem Software-Interrupt können ebenfalls den Übergang verursachen; zum Beispiel kann in einem präemptiven Multitasking-System ein Timer-Interrupt den Ablauf des Schedulers auslösen.

+0

Also, sind diese beiden die einzigen Situationen, wenn die CPU in den Kernel-Modus geht? – claws

+0

@claws, es ist vollständig Prozessor, Betriebssystem und Implementierung abhängig. –

+0

Der Kommentar zu Systemaufrufen über einen Interrupt ist etwas veraltet. Älteres Linux verwendete Interrupt 0x80, um bei einem Systemaufruf in den Kernel-Modus zu wechseln. Aber mit neueren Prozessoren (wo neu ist alles> Pentium 2) und Linux-Kernel, gab es eine Umstellung auf die Verwendung der "schnellen Systemaufruf" -Funktion, die über synester Anweisungen zur Verfügung gestellt wird. Sehen Sie sich http://articles.manugarg.com/systemcallinlinux2_6.html – Jasmeet

1

Wenn Sie in Windows einen Systemaufruf ausführen, rufen die Bibliotheksroutinen einen Kernel-Einsprungpunkt im Adressraum des Betriebssystems auf. Es wiederum versetzt die CPU in den Supervisor-Modus, indem es eine für diesen Zweck spezifische Anweisung ausführt, wie zum Beispiel sysenter. Was es tut, ist im Wesentlichen ein Bit im Flags-Register zu setzen. Dadurch kann das Betriebssystem privilegierte Anweisungen verwenden.

3

Mein Verständnis ist, dass jedes Programm, dessen Segmentregister haben die beiden LSBs Null im Kernel-Modus ausgeführt werden soll, während ein Programm, dessen Segmentregister haben die beiden LSBs = 1 wird in Benutzer ausgeführt werden, Modus. Tatsächlich definieren die beiden LSBs des Segments rgeisters das Privileged Level (0 am höchsten bis 3 am niedrigsten)

Also, um ein Programm im Kernel-Modus laufen zu lassen, müssen Sie die Segmentregister auf 0010 hex setzen (ich glaube). Ich bin mir nicht sicher, wie Sie ein Programm in diesen Speicherplatz einfügen können, ohne etwas anderes zu überschreiben - mit anderen Worten, wie stellt der Linker dies sicher? Wenn Sie den Kernel-Moduscode aus dem Benutzermoduscode aufrufen möchten, müssen Sie herausfinden, wie Parameter übergeben werden - sie verwenden nicht die gleiche Speicherkapazität, können also keine Daten nach Speicherreferenz übergeben. Ich denke, du musst es in Registern weitergeben.

Wenn jemand die Lücken in den obigen füllen kann, wäre ich sehr dankbar.