Es ist kompliziert. ;)
Nein, das ist es wirklich.
IRQL steht für "Interrupt Request Level". Diese Zahl reicht von 0 bis 31 auf Windows x86-Systemen und von 0 bis 15 auf x64-Systemen. Es stellt die "Wichtigkeit" einer Kernelmodusaufgabe im Verhältnis zu anderen Kernelmodusaufgaben dar.
IRQL ist ein von Windows definierter Status des Prozessors - nicht eines Prozesses oder Threads -, der Windows anzeigt, ob das, was der Prozessor gerade macht, durch andere Tasks unterbrochen werden kann. Wenn eine neue Task (z. B. eine Interrupt-Service-Routine) eine höhere IRQL als die aktuelle IRQL des Prozessors aufweist, kann die aktuelle Task mit Ja unterbrochen werden. sonst nein Bei einem Multiprozessorsystem verfügt jeder Prozessor über eine eigene IRQL. Dazu gehören die durch Hyperthreading erzeugten "Logical Processors".
(Ich verwende das Wort "Wichtigkeit" anstelle von "Priorität", da "Priorität" in Windows sich auf Thread-Prioritäten bezieht und IRQLs etwas anderes sind. Im Gegensatz zu Thread-Prioritäten sind Kernel-Tasks auf derselben IRQL nicht zeitaufgelöst und IRQLs sind nicht '). t unterliegen automatischem Boost und Decay.)
(Ich sollte auch erwähnen, dass der Begriff "Kernel-Task" hier nicht offiziell ist. Windows nennt diese Dinge nicht wirklich "Kernel-Tasks"), sie sind keine verwalteten Objekte, wie z. B. Prozesse und Threads, und es gibt keine Beziehung zu x86-Task gates "und nichts in" Task Manager "angezeigt. Wenn ich (und andere) den Begriff hier verwenden," deckt "" Kernel-Modus-Task "wirklich alles ab, was einen definierten Anfang und ein Ende hat, das im Kernel-Modus bei IRQL 2 oder im Kernel-Modus ausgeführt werden muss "Eine Interrupt-Service-Routine ist ein Beispiel für eine" Kernel-Modus-Task "; dies gilt auch für eine DPC-Routine. Ein anderes Beispiel kann Code in einem Kernel-Mode-Thread sein. Solche Threads beginnen bei IRQL 0, sind jedoch Teil des Codes wirftzu IRQL 2 oder höher führt etwas aus und kehrt dann zu seiner vorherigen IRQL zurück. Der High-IRQL-Teil des Codes ist ein Beispiel für das, was ich hier "Kernel-Task" nenne. )
Der Systemmonitor zeigt die Zeit, die bei IRQL 2 verbracht wurde, als "% DPC-Zeit" und die Zeit bei IRQL> 2 als "% Interrupt-Zeit" an, unabhängig davon, ob die Zeit tatsächlich in einer DPC-Routine oder einer ISR verbracht wurde oder das Ergebnis der Erhöhung von IRQL war ein niedrigerer Wert. Jedes ist eine Teilmenge dessen, was PerfMon als "% privilegierte Zeit" anzeigt - was als "Kernelmoduszeit" bezeichnet werden sollte.
Sobald eine Kernel - Aufgabe bei IRQL 2 oder höher gestartet wird, läuft es bis zur Fertigstellung, bevor irgendetwas anderes an der gleichen IRQL auf dem gleichen Prozessor gestartet. Sie kann durch eine Task mit höherem IRQL unterbrochen werden (die wiederum durch einen Task mit noch höherem IRQL usw. unterbrochen werden könnte), aber wenn die Task mit höherem IRQL abgeschlossen ist, kehrt die Steuerung zu der Task zurück, die sie unterbrochen hat.
IRQL ist in erster Linie ein Serialisierungsmechanismus . (Viele sagen "Synchronisation", aber ich bevorzuge dieses Wort, da es das Ergebnis genauer beschreibt.) Es soll sicherstellen, dass mehrere Tasks auf derselben CPU, die auf bestimmte gemeinsam genutzte Ressourcen zugreifen - meist gemeinsam genutzte Datenstrukturen im Kernelbereich des Betriebssystems -. dürfen sich nicht auf eine Weise unterbrechen, die diese Strukturen beschädigen könnte.
Beispielsweise werden viele Daten im Windows-Kernel, insbesondere die Speicherverwaltungsdaten und die vom Thread-Scheduler verwendeten Daten, bei IRQL 2 "serialisiert". Dies bedeutet, dass jede Task, die solche Daten ändern möchte, ausgeführt werden muss IRQL 2, wenn dies der Fall ist. Wenn ein Task mit einer höheren IRQL-Datenbank versucht, solche Daten zu schreiben, kann dies zu einer Beschädigung führen, da er möglicherweise eine IRQL2-Task unterbrochen hat, die sich in einem Lese-Modifizierungs-Schreibzyklus für dieselben Daten befindet. Das heißt, Aufgaben mit höherem IRQL dürfen dies einfach nicht.
Aufgaben mit höherem IRQL sind meistens die Interrupt-Service-Routinen von Gerätetreibern, da alle Interrupts der Geräte bei IRQL> 2 auftreten. Dies umfasst den Interrupt des Zeitgeberchips auf der Hauptplatine, der die Zeitnahme und die zeitgesteuerte Aktivität im Betriebssystem steuert. Seine IRQL-Werte liegen über denen aller "normalen" Hardwaregeräte.
IRQLs 2 und höher werden für Kernel-Tasks verwendet, die nicht durch Hardware-Interrupts ausgelöst werden, bei denen jedoch eine normale Thread-Planung - einschließlich Warten - nicht auftreten kann. Sobald sich ein Prozessor auf IRQL 2 oder höher befindet, können auf diesem Prozessor keine Thread-Kontextwechsel erfolgen, bis IRQL unter 2 fällt.
Der Benutzermoduscode ist immer auf IRQL 0. Der Kernelmoduscode kann bei jedem IRQL von 0 bis zu jedem beliebigen Maximum ausgeführt werden. IRQL 1 ist ein Sonderfall. Dies ist nur der Kernel-Modus, hat jedoch keine Auswirkungen auf die Zeitplanung und ist eigentlich eher ein Status eines Threads als des Prozessors - er wird beispielsweise während Thread-Kontextwechseln gespeichert und wiederhergestellt.
Um verschiedene Serialisierungsgarantien aufrechtzuerhalten, sind die meisten Ausnahmen (z. B. Division durch Null oder Speicherzugriffsverletzungen wie Seitenfehler) in IRQL 2 oder höher einfach nicht handhabbar. (IRQL 2 btw wird allgemein als "Versandebene" oder "DPC-Stufe" bezeichnet.)
Und jetzt können wir diesen Fehlercode endlich erklären!
Der häufigste Fall von IRQL_NOT_LESS_OR_EQUAL ist auf einen Seitenfehler (Versuch, auf eine "nicht residente" virtuelle Adresse zuzugreifen) oder eine Speicherzugriffsverletzung (Versuch, auf eine schreibgeschützte Seite zu schreiben oder auf eine nicht definierte Seite zuzugreifen) zurückzuführen überhaupt), das tritt bei IRQL 2 oder höher auf.
Wenn solche Ausnahmen bei IRQL 0 oder 1 ausgelöst werden, können sie entweder durch vom System bereitgestellten Code (wie der Seitenfehlerhandler) oder durch einen vom Entwickler bereitgestellten Ausnahmehandler "gehandhabt" werden. Die meisten Ausnahmen können jedoch nicht behandelt werden, wenn sie bei IRQL 2 oder höher aufgetreten sind.
Also ... der Bugcheck-Code bedeutet "eine Ausnahme eines Typs, der nur bei IRQL 0 oder 1 gehandhabt werden kann, als IRQL bei 2 oder höher war." dh "nicht kleiner oder gleich 1". Merkwürdige Formulierung, aber da ist es.
Es gibt einige andere Dinge, die diese Fehlerüberprüfung auslösen können, und der Wert, den der IRQL-Wert nicht kleiner oder gleich ist, ist nicht immer 1, tritt jedoch nur selten auf. Die WinDBG-Dokumentation listet sie auf.