Da die CPU im Benutzer-/Kernelmodus läuft, möchte ich wissen, wie dies vom Kernel bestimmt wird. Ich meine, wenn ein Sys-Call aufgerufen wird, führt der Kernel ihn im Auftrag des Prozesses aus, aber wie weiß der Kernel, dass er im Kernelmodus ausgeführt wird?
Antworten
Zu viele Anzeigen?Sie können anhand des Privilegienlevels im im Code-Segment-Register (CS) feststellen, ob Sie im Benutzermodus oder im Kernelmodus sind. Jede Instruktion, die in die CPU geladen wird, stammt aus dem Speicher, auf den der RIP- oder EIP-Register zeigt (je nachdem, ob Sie x86_64 oder x86 sind), und wird aus dem Segment gelesen, das in der globalen Deskriptorentabelle (GDT) durch den aktuellen Code-Segment-Deskriptor beschrieben wird. Die unteren zwei Bits des Code-Segment-Deskriptors bestimmen das aktuelle Privilegienlevel, auf dem der Code ausgeführt wird. Wenn ein Systemaufruf gemacht wird, der typischerweise durch einen Software-Interrupt erfolgt, überprüft die CPU das aktuelle Privilegienlevel und tauscht, wenn es sich im Benutzermodus befindet, den aktuellen Code-Segment-Deskriptor gegen einen Kernel-Level-Deskriptor aus, wie im Software-Interrupt-Gate-Deskriptor des Systemaufrufs bestimmt, und führt einen Stack-Wechsel durch sowie speichert die aktuellen Flags, den Benutzer-Level-CS-Wert und den RIP-Wert auf diesem neuen Kernel-Level-Stack. Nach Abschluss des Systemaufrufs werden der Benutzermodus-CS-Wert, die Flags und der Instruktionszeiger (EIP oder RIP) vom Kernel-Stack wiederhergestellt, und es erfolgt ein Wechsel zurück zum Stack des aktuellen ausführenden Prozesses.
Der Kernel-Code wird nur im Kernel-Modus ausgeführt. Auf keine Weise kann Kernel-Code im Benutzermodus ausgeführt werden. Wenn die Anwendung ein Systemaufruf aufruft, wird eine Trap (Software-Interrupt) generiert und der Modus wird in den Kernel-Modus umgeschaltet, wo die Kernel-Implementierung des Systemaufrufs ausgeführt wird. Sobald dies erledigt ist, wird der Kernel wieder in den Benutzermodus umgeschaltet und die Benutzeranwendung wird im Benutzermodus fortgesetzt.
Der Begriff heißt "Superviser-Modus", der sowohl auf x86/ARM als auch auf vielen anderen Prozessoren gilt.
Lesen Sie dies (was nur auf x86-CPU zutrifft):
http://en.wikipedia.org/wiki/Ring_(computer_security)
Ring 0 bis 3 sind die verschiedenen Privilegien-Ebenen der x86-CPU. Normalerweise werden nur Ring 0 und 3 verwendet (Kernel und Benutzer), aber heutzutage findet auch Ring 1 Verwendungen (z. B. VMWare verwendet es, um die Ausführung von Ring 0 des Gastes zu emulieren). Nur Ring 0 hat das volle Privileg, einige privilegierte Anweisungen auszuführen (wie lgdt oder lidt), und daher ist ein guter Test auf Assemblerebene natürlich die Ausführung dieser Anweisungen und die Überprüfung, ob Ihr Programm auf eine Ausnahme stößt oder nicht.
Lesen Sie dies, um Ihr aktuelles Privilegenniveau wirklich zu identifizieren (suchen Sie nach CPL, was eine Veranschaulichung von Jasons Antwort ist):
http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection
Es handelt sich um eine einfache Frage und benötigt keinen Expertenkommentar wie oben angegeben...
Die Frage lautet, wie erkennt eine CPU, ob sie sich im Kernelmodus oder im Benutzermodus befindet. Die Antwort lautet "Modusbit"...
Es handelt sich um ein Bit im Statusregister des Registersatzes der CPU. Wenn "Modusbit=0" ist, wird es als Kernelmodus angesehen (auch als Überwachungsmodus, privilegierter Modus, geschützter Modus usw...) Wenn "Modusbit=1" ist, wird es als Benutzermodus angesehen... und der Benutzer kann nun seine persönlichen Anwendungen ohne spezielle Kernelunterbrechungen ausführen.
also ganz einfach... nicht wahr??