Was ist die Ursache für einen doppelten Fehler in der CPU?

924
Nik Novák

Es ist meine Annahme, wenn ich sage, dass Doppelfehler nur im Kernelmodus des Prozessors (oder Ring 0 für x86) auftreten kann und muss, wenn eine Ausnahme (synchron) auftritt und nie sonst?

Lautet die Antwort "Ja", können wir bei neueren Prozessoren, die mit älteren kompatibel sind, nicht in Code, der im Kernelmodus ausgeführt wird, bereits definierte Anweisungen (in neuerer CPU) verwenden, wenn wir diese Kompatibilität im Hinblick auf undefinierte Anweisungen beibehalten möchten Ausnahme, ist es richtig? Und noch eine Frage. Wenn die CPU einen Code ausführt, der im Kernelmodus ausgeführt wird, muss er im Grund des Seitenfehlers im Speicher angezeigt werden, nicht wahr?

Und mein zusätzlicher Gedanke. Gibt es irgendwelche Vorteile daraus, dass es "internes INT-Aktivierungsbit" im Statusregister implementiert wird, das automatisch gesetzt und gelöscht wird, wenn ein Interrupt / eine Ausnahme auftritt und wenn es eine Ausnahme gibt, liest HW dieses Bit und wenn es gesetzt ist, springt es zu Ausnahme-Handler-Adresse, sonst springt ir zum Doppel-Fehler-Handler?

Wenn es von der Architektur / dem Betriebssystem abhängig ist, wähle ich Linux für MIPS.

Entschuldigung für mein Englisch.

0
Ich empfehle Ihnen, Ihre Frage an StackOverflow zu senden. Ihre Frage hat viel mit Hardware zu tun, aber es gibt hier nur sehr wenige Assembler-Programmierer oder Kernel-Hacker, und das ist ein wenig über meinem Kopf. Viel Glück. Frank Thomas vor 8 Jahren 1
Sie werden diese Migration ablehnen ... Ramhound vor 8 Jahren 0
Es gibt weder Code noch eine Anfrage dafür, warum geht es hier nicht um ein Thema? Ramhound vor 8 Jahren 1
In Anbetracht dessen, dass es dort vier Fragen zu geben scheint, stimme ich zu nah, um zu weit zu sein. DavidPostill vor 8 Jahren 0

2 Antworten auf die Frage

2
Frank Thomas

Die beste Antwort, die ich Ihnen geben kann, ist: Ja, es ist richtig, dass bei den meisten modernen CPUs nur im Kernelmodus ausgeführter Code einen doppelten oder dreifachen Fehler auslösen kann . Es ist sehr selten (aber nicht unmöglich), dass ein nicht vom Kernel initiierter Befehl aufgrund des ProtectedMode-Vorgangs einen schwerwiegenden Fehler auslöst, der die physische Adressierung so abstrahiert, dass eine Verzweigung in eine ungültige Registeradresse nicht mehr möglich ist.

Ja, jeder Maschinencode, der für eine CPU ohne ProtectedMode zusammengestellt wurde, sollte zumindest neu zusammengesetzt werden, wenn er nicht geändert wird, um mit einer neueren CPU zu arbeiten.

Von Wikipedia: https://en.wikipedia.org/wiki/Protected_mode#Virtual_8086_mode

Virtueller 8086-Modus Hauptartikel: Virtueller 8086-Modus

Mit der Veröffentlichung des 386 bietet der Protected Mode den von den Intel-Handbüchern als virtuellem 8086-Modus bezeichneten Modus. Der virtuelle 8086-Modus ermöglicht es, Code, der zuvor für den 8086 geschrieben wurde, unverändert und gleichzeitig mit anderen Aufgaben auszuführen, ohne die Sicherheit oder die Systemstabilität zu beeinträchtigen. [29]

Der virtuelle 8086-Modus ist jedoch nicht mit allen Programmen vollständig abwärtskompatibel. Programme, die Segmentmanipulationen, privilegierte Anweisungen, direkten Hardwarezugriff oder die Verwendung von selbstmodifizierendem Code erfordern, erzeugen eine Ausnahme, die vom Betriebssystem bereitgestellt werden muss. [30] Darüber hinaus generieren Anwendungen, die im virtuellen 8086-Modus ausgeführt werden, einen Trap mit Anweisungen, die Eingabe / Ausgabe (E / A) umfassen, was die Leistung beeinträchtigen kann. [31]

Aufgrund dieser Einschränkungen können einige Programme, die ursprünglich für den 8086 ausgeführt wurden, nicht im virtuellen 8086-Modus ausgeführt werden. Infolgedessen muss die Systemsoftware beim Umgang mit Legacy-Software die Systemsicherheit beeinträchtigen oder die Abwärtskompatibilität beeinträchtigen. Ein Beispiel für einen solchen Kompromiss ist bei der Veröffentlichung von Windows NT zu sehen, die die Kompatibilität mit "schlecht verhaltenen" DOS-Anwendungen rückgängig machte. [32]

Ich hoffe, das hilft ein wenig, und wenn es nicht ausreicht, kann ein anderer Lücken in meinem Verständnis schließen.

Vielen Dank für Ihre Antwort, aber leider wurde meine Frage nicht beantwortet. Mit einer neueren CPU meine ich nicht den Übergang zwischen einem Prozessor, der mit realen Adressen arbeitet, und dem, der mit virtuellen Adressen arbeitet. Ich meinte, wenn der Nachfolger einiger CPUs (beide unterstützen virtuelle Adressierung mit einem gewissen Schutz und sind vollständig vorwärtskompatibel) einige neue Anweisungen hinzugefügt, wenn diese Anweisungen im Kernelmodus einer Software verwendet werden können, die auf beiden dieser CPUs ausgeführt wird. In diesem Fall würde eine CPU im Kernelmodus aufgrund einer undefinierten Befehlsausnahme einen Doppelfehler auf einer älteren CPU auslösen, stimmt das nicht? Nik Novák vor 8 Jahren 0
Eine undefinierte Befehlsausnahme führt zu einem doppelten / dreifachen Fehler, wenn es sich um den in einer Interrupt- oder Ausnahmeroutine angegebenen Befehl handelt. Wenn es jedoch in normalem Code ist, sollte es nicht. Der Fehler tritt auf, und die Verzweigung zur Ausnahmebehandlung sollte normal erfolgen. Ich kann nicht ganz sehen, wo der geschützte oder der Kernel-Modus dazu kommt. Planen Sie die Ausführung von Code als Kernel, um die Kompatibilität im geschützten Modus zu umgehen und zu fragen, ob dieser Ansatz Probleme verursachen kann? denn ja könnte es. wird es? hängt vom Code und der Hardware ab. Frank Thomas vor 8 Jahren 0
Vielen Dank für Ihre Antwort. Nein, das ist nicht mein Plan. Sie möchten also sagen, wenn "normaler" Code im Kernelmodus ausgeführt wird, tritt die Ausnahme nicht direkt auf, sondern der doppelte Fehlerhandler, aber der entsprechende Ausnahmehandler wird aufgerufen. Wenn ja, wo liegt dann der Unterschied zwischen "normalem" Code und Interrupt-Handler-Code, und woher weiß die CPU, welcher Ausnahmehandler aufgerufen werden soll? (bedeutet einen Ausnahmebehandler im Vergleich zu einem Doppelfehlerbehandler) Nik Novák vor 8 Jahren 0
Ein doppelter Fehler tritt auf, wenn ein Fehler vorliegt und wenn die CPU versucht, den Fehler zu behandeln, tritt ein anderer Fehler innerhalb des Handlers auf. Doppelfehler können nur im Handlercode auftreten. Ist die betreffende Anweisung also Teil eines Exception / Interrupt-Handlers? Wenn dies der Fall ist, kann dies zu einem doppelten Fehler führen. wenn nicht, kann es nicht. Frank Thomas vor 8 Jahren 0
Vielen Dank für Ihre Antwort. Durch Sie kann Kernel-Thread normalerweise Ausnahmen verursachen? (Das bedeutet nicht Programmierfehler, aber zum Beispiel die bereits erwähnte undefinierte Anweisung, möglicherweise Seitenfehler (ausgelagert, wenn dies für Kernel-Thread möglich ist). Es hat einige Logik, aber wie die CPU erkennt, ob dies ein Interrupt / Exception-Handler ist, kein Kernel-Thread verursacht eine Ausnahme (beide laufen im CPU-Kernel-Modus)? Nik Novák vor 8 Jahren 0
das geht über mich hinaus Ich weiß, dass die meisten CPUs ein Interrupt-Register haben, das Vektoren von Adressen enthält, die Anweisungen enthalten, die im Falle des Interrupts ausgelöst werden sollen, aber ich weiß nicht, was die Anweisungen in diese Adressen steckt oder wie die Anweisungen definiert werden. Frank Thomas vor 8 Jahren 0
Trotzdem danke ich Ihnen für Ihre Zeit, aber ich kann Ihre Antwort nicht akzeptieren, da sie meine Frage nicht direkt beantwortet. Aber diese Diskussion war für mich sehr nützlich. Nik Novák vor 8 Jahren 0
0
John Burger

Ich habe viel Erfahrung mit dem x86, aber nichts zu MIPS, sorry - aber ich glaube, dass die folgende Beschreibung trotzdem gilt.

Ein Doppelfehler nur auftritt, in einem ganz besonderen Umstand: Wenn beim Versuch zu starten ein Exception - Handler, ein weitere Ausnahme auftritt, dann wird die erste Ausnahme wird aufgegeben und die Doppelfehler Exception - Handler wird stattdessen genannt.

Hier ist ein Beispiel eines einfachen Fehlers. Wenn Code versucht, auf ungültigen Speicher zuzugreifen:

*(int *)0 = 0xdead; 

Dann erkennt die CPU die NULL-Zeigerreferenz und versucht, den Speicherfehler-Handler zu starten. Dies könnte im Code für Benutzer (Ring 3) oder Supervisor (Ring 0) sein, und es würde kein Doppelfehler auftreten - die CPU würde einfach versuchen, den Speicherfehler-Handler zu starten.

Stellen Sie sich jedoch vor, das Betriebssystem hatte einen Fehler und der Speicherfehler-Handler selbst befand sich in einem ungültigen Speicher. Beim Versuch, den Handler für Speicherfehler zu starten, ist ein weiterer Fehler aufgetreten, und der erste Fehler konnte nicht behandelt werden. Der Double-Fault-Handler würde dann aufgerufen. (Wenn beim Versuch, den Double Fault-Handler zu starten, ein Fehler auftritt, wird die x86-CPU einfach mit einem dreifachen Fehler heruntergefahren. Die PC-Hardware erkennt dies und setzt die CPU zurück.)

Ich habe wiederholt auf Start hingewiesen, da nach dem erfolgreichen Start eines Fehlerbehandlers kein Doppelfehler mehr auftritt. Der erste Fehler wurde behoben, und die CPU kann jetzt alle neuen Fehler behandeln. Die CPU "erinnert sich nicht" daran, dass sie sich in einem Fehlerhandler befindet, und verursacht einen Doppelfehler, wenn ein neuer Fehler auftritt.

Wenn ein Fehlerhandler in Ihrem Beispiel versucht, einen undefinierten Opcode zu verwenden, wird der Undefined Opcode-Fehlerhandler einfach für diese Anweisung aufgerufen. Es handelt sich nicht um einen Doppelfehler, sondern lediglich um einen Fehler.

Wenn der Speicherfehler-Handler startet und während der Verarbeitung einen Speicherfehler verursacht, wird der Speicherfehler-Handler natürlich neu gestartet. Dies kann zu einem erneuten Speicherfehler führen, wodurch der Speicherfehler-Handler erneut gestartet wird - jedes Mal, wenn mehr und mehr Stapel verwendet werden, bis schließlich der Stapel selbst überläuft, was auf dem x86 ein anderer Fehlerbehandler ist.