Che cos'è l'IRQL (Interrupt Request Level) in Windows e come si relaziona ai BSOD?

Ultimo aggiornamento: 01/10/2025
Autore: Isaac
  • IRQL definisce le priorità di esecuzione e maschera gli interrupt in base al livello; sopra DISPATCH comanda l'IRQL, non la priorità del thread.
  • I BSOD Gli errori 0xA/0xD1 sono solitamente causati da accessi a memoria paginabile o non valida con IRQL elevato e indirizzi o codice paginabile non corretti.
  • WinDbg e Driver Verifier sono fondamentali: utilizzare !analyze, !irql, ln, .trap, !pool, !address ed esaminare i parametri 1, 3 e 4.
  • En driver, previene gli errori di pagina con IRQL elevati, utilizza memoria non paginata e blocchi di spin; per l'utente, aggiorna/isola i driver problematici.

irq

Se hai mai visto una schermata blu con messaggi come IRQL_NOT_LESS_OR_EQUAL o DRIVER_IRQL_NOT_LESS_OR_EQUAL, probabilmente ti sei imbattuto in un concetto poco conosciuto al di fuori del mondo dei driver: l'IRQL (Interrupt Request Level). In Windows, questo livello di priorità di interrupt ha la precedenza sulla priorità del thread quando il sistema supera una certa soglia, e ciò ha conseguenze dirette sulla stabilità.

Nelle prossime righe troverete una visita guida completa e in spagnolo dalla Spagna su cosa è l'IRQL, come funziona, perché genera schermate blu, come diagnosticare il problema con WinDbg e cosa fare se si riscontra l'errore da parte dell'utente o si sviluppano driver in modalità kernel. Andiamo al dunque.

Che cosa è IRQL (Interrupt Request Level) in Windows?

In Windows, il IRQL definisce la priorità di hardware in cui opera un processore In qualsiasi momento. All'interno del Windows Driver Model (WDM), il codice in esecuzione a un IRQL basso può essere interrotto da codice in esecuzione a un IRQL più alto. Infatti, su un singolo computer multi-core, ogni CPU può avere un IRQL diverso, il che complica la sincronizzazione.

C'è una regola fondamentale: Quando una CPU funziona a un IRQL superiore a PASSIVE_LEVEL, può essere preemptata solo da attività a un IRQL ancora più alto.In questo modo si organizza la coesistenza tra codice utente, funzioni kernel, chiamanti differiti (DPC) e routine di servizio di interruzione del dispositivo (ISR).

Errore 0x0000000A
Articolo correlato:
Errore 0x0000000a (schermata blu della morte). 6 soluzioni

Livelli e priorità: PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL e DIRQL

In termini generali, Su x86 vengono utilizzati valori IRQL compresi tra 0 e 31; su x64, tra 0 e 15Il significato pratico è lo stesso: IRQL 0 (PASSIVE_LEVEL) è il punto in cui vengono eseguiti il ​​normale codice utente e molte funzioni del driver; APC e errori di pagina Di solito sono mappati su IRQL 1 (APC_LEVEL); IRQL 2 (DISPATCH_LEVEL) comprende lo scheduler dei thread e i DPC. Al di sopra di DISPATCH_LEVEL ci sono livelli riservati agli interrupt del dispositivo (noti come DIRQL) e ad altri usi interni come HIGH_LEVEL.

Nell'ecosistema dei conducenti, Molte routine comuni vengono eseguite a DISPATCH_LEVEL: ad esempio, DPC e StartIo. Questa progettazione garantisce che, mentre una di esse sta interagendo con code interne o altre risorse condivise, un'altra routine allo stesso livello non la prelazioni su quella CPU, perché la regola di prelazione consente solo interrupt a livelli superiori.

Tra DISPATCH_LEVEL e i livelli di profilazione/alti c'è spazio per il interrupt hardware di ciascun dispositivo (DIRQL)L'IRQL di un dispositivo definisce la sua priorità rispetto agli altri dispositivi. Un driver WDM ottiene questo IRQL durante IRP_MJ_PNP con IRP_MN_START_DEVICE. Questo IRQL del dispositivo non è un valore globale fisso, ma piuttosto il valore associato a una specifica linea di interrupt.

Priorità IRQL vs. Thread

È opportuno non confondere i concetti: La priorità del thread determina quando lo scheduler interviene e quale thread esegue; l'IRQL controlla quale tipo di attività può essere eseguita e quali interrupt vengono mascherati. Oltre il DISPATCH_LEVEL, non c'è alcun cambio di thread: è l'IRQL che controlla, non la priorità del thread.

  Valve Fremont: specifiche trapelate e indizi chiave

IRQL e paging: cosa non dovresti fare

Un effetto immediato dell'aumento dell'IRQL è che il sistema non può gestire gli errori di paginaRegola d'oro: il codice in esecuzione a DISPATCH_LEVEL o superiore non può causare errori di pagina. In pratica, ciò significa che tali routine e i dati che toccano deve risiedere nella memoria non paginataInoltre, alcuni helper del kernel limitano il loro utilizzo in base a IRQL: ad esempio, KeWaitForSingleObject DISPATCH_LEVEL può essere chiamato solo se non si sta bloccando (timeout zero) e, per timeout diversi da zero, è necessario essere al di sotto di DISPATCH_LEVEL.

Controllo implicito ed esplicito di IRQL

La maggior parte delle volte, il sistema stesso richiama le tue routine all'IRQL corretto per quello che dovrebbero fare. Le routine di dispatch per gli IRP vengono eseguite a LIVELLO PASSIVO (possono bloccare o chiamare qualsiasi helper), StartIo e DPC vengono eseguite a LIVELLO DISPATCH per proteggere le code condivise e gli ISR ​​vengono eseguiti a LIVELLO DIRQL.

Se hai bisogno di controllarlo esplicitamente, È possibile aumentare e diminuire l'IRQL con KeRaiseIrql y KeLowerIrqlEsiste una scorciatoia molto utilizzata: KeRaiseIrqlToDpcLevel() restituisce l'IRQL precedente e ti lascia a DISPATCH_LEVEL. Importante: non abbassare mai l'IRQL al di sotto del valore in cui si trovava quando il sistema ti ha chiamato; interrompere quella sincronizzazione può aprire finestre di gara molto serie.

Errori di schermata blu relativi a IRQL: IRQL_NOT_LESS_OR_EQUAL e DRIVER_IRQL_NOT_LESS_OR_EQUAL

IRQL

Due classici controlli dei bug associati a questi problemi sono IRQL_NON_MENO_O_UGUALE (0xA) y DRIVER_IRQL_NON_MENO_O_UGUALE (0xD1)Entrambi indicano un tentativo di accesso a un indirizzo paginabile (o non valido) con un IRQL troppo alto. Ciò è solitamente dovuto all'utilizzo di indirizzi errati da parte dei driver, alla dereferenziazione di puntatori errati o all'esecuzione di codice paginabile a livelli inappropriati.

Nel caso specifico di DRIVER_IRQL_NON_MENO_O_UGUALE (0x000000D1), i parametri sono molto informativi: 1) indirizzo di memoria referenziato; 2) IRQL in quel momento; 3) tipo di accesso (0 lettura, 1 scrittura, 2/8 esecuzione); 4) indirizzo dell'istruzione che ha fatto riferimento alla memoria. Con il debugger è possibile utilizzare ln sul parametro 4 per elenca il simbolo più vicino e scopri quale funzione era in esecuzione.

Cause comuni da tenere a mente

Oltre al codice specifico, ci sono degli schemi che si ripetono. Dereferenziazione di un puntatore non valido a DISPATCH_LEVEL o superiore Questa è una ricetta sicura per il disastro. Anche l'accesso a dati paginabili a quel livello, o l'esecuzione di codice paginabile (ad esempio, una funzione contrassegnata come paginabile), attiva il controllo dei bug.

Altri casi comuni includono chiamare una funzione in un altro driver che è già stato scaricato (puntatore a funzione sospeso) o richiamato indirettamente tramite un puntatore a funzione non valido. Spesso, se il sistema è in grado di identificare un modulo, il suo nome verrà visualizzato sulla schermata blu stessa e verrà anche salvato in KiBugCheckDriver, accessibile con dx KiBugCheckDriver da WinDbg.

Un dettaglio pratico: Nella maggior parte dei D1/A, il vero problema non è l'IRQL stesso, ma piuttosto l'indirizzo di memoria referenziato. Ecco perché i parametri 1, 3 e 4 sono cruciali per focalizzare la diagnosi.

Diagnostica con WinDbg: Comandi utili e lettura dei parametri

Per lavorare su questi casi, WinDbg è lo strumento chiave, e se il BSOD menziona ntoskrnl.exe Queste informazioni forniscono molte indicazioni per stabilire se l'errore è nel sottosistema del kernel. Inizia con !analyze -v per ottenere un riepilogo del controllo dei bug, dello stack e, se sei fortunato, del modulo coinvolto. Se il dump include un frame di cattura, .trap ti mette nel contesto della CPU guasta.

I comandi di mucchio come k, kb, kc, kd, kp, kP, kv Ti mostrano diversi livelli di dettaglio del backtrace. Con ln sul parametro 4 puoi saltare all'istruzione che faceva riferimento alla memoria e ottenere il simbolo vicino. E se sospetti che il livello di priorità sia in esecuzione prima dell'interruzione, !irql mostra l'IRQL salvato per il processore di destinazione (ad esempio DISPATCH_LEVEL).

  Come controllare lo schermo Android con SCRCPY su Windows

Per analizzare la direzione del parametro 1, !pool Ti dirà se appartiene a un pool di paging; !address y !pte approfondire la mappatura della memoria di quell'area. Puoi usare i comandi di visualizzazione della memoria per ispezionare il contenuto a cui si è tentato di accedere. Infine, u, ub, uu consentono di disassemblare attorno all'indirizzo del parametro 4.

Non dimenticare lm t n per elencare i moduli caricati y !memusage per lo stato generale della memoria. Se KiBugCheckDriver ha qualcosa, dx KiBugCheckDriver Restituirà il nome del modulo Unicode: in un esempio tipico, “Wdf01000.sys” è stato visto come il driver coinvolto durante il controllo dei bug.

Strumenti di sistema: Driver Verifier, Visualizzatore eventi e Diagnostica

El Verificatore del conducente Esamina il comportamento dei driver in tempo reale e forza errori quando rileva un utilizzo errato delle risorse (come il pool), sollevando un'eccezione per isolare l'area problematica del codice. Viene avviato con verifier da simbolo del sistema ed è consigliabile selezionare il set di driver più piccolo possibile per evitare di aggiungere troppo overhead.

Se non ti vedi con WinDbg, applicare misure di base: Controllare il registro di sistema in Visualizzatore eventi per verificare la presenza di errori che puntano a un dispositivo/driver specifico; aggiornare o disabilitare il driver segnalato dalla schermata blu; verificare la compatibilità hardware con la versione di Windows in uso; e utilizzare Diagnostica memoria di Windows se si sospetta un problema con la RAM. Queste azioni, sebbene semplici, risolvono un gran numero di casi.

Casi reali: quando i BSOD sembrano casuali

Un utente con Windows 10 Pro (CPU AMD Ryzen 5 3400G, GPU NVIDIA Scheda grafica GeForce GTX 1660 Ti e Gigabyte B450 AORUS PRO WIFI, 16 GB di RAM) presentava schermate intermittenti "IRQL_LESS_OR_NOT_EQUAL". Avevo già aggiornato i driver essenziali (rete, scheda grafica), installato tutti gli aggiornamenti di Windows ed eseguito lo strumento di memoria, il tutto senza rilevare alcun problema.

In scenari come questo, Il passo successivo è analizzare i dump con WinDbg e cercare modelli: processi coinvolti quando cade (ad esempio, explorer.exe), moduli di interfaccia grafica (win32kfull.sys) e funzioni come xxxProcessNotifyWinEvent che appare nello stack. Sebbene questo modulo sia Windows, il trigger è spesso un driver di terze parti (schede grafiche, di input, di overlay, di acquisizione) che utilizza la memoria a un IRQL inappropriato e l'errore si verifica entro win32k.

La raccomandazione pratica qui è disattivare temporaneamente il software di sovrapposizione (acquisizione, GPU OSD), driver di periferiche software aggressivi (mouse/tastiere con macro) e versioni beta dei driver grafici, per poi restringere il campo. L'utilizzo di Driver Verifier sui problemi sospetti può aiutare a circoscrivere il problema con uno stack più chiaro.

Un modello di rete molto comune: ndis.sys non è sempre il colpevole

Un altro caso tipico: screenshot con ndis.sys (il livello di rete di Windows). Su un computer reale, il sistema si bloccava immediatamente all'avvio. La soluzione pratica era quella di avviare in Modalità sicura senza funzioni di rete, aprire il Amministratore del dispositivo e disabilitare gli adattatori in "Schede di rete" per isolare il problema.

In quella squadra c'era un Controller della famiglia Realtek PCIe GBE e un Atheros AR5007GDisattivando entrambi, è stato rilevato che la vera causa era la athrx.sys (Atheros), nonostante la schermata blu menzionata ndis.sysIl dump lo ha confermato: lo stack è passato attraverso ndis!NdisFreeTimerObject ma il modulo colpevole era athrx.sysLa correzione finale è stata disinstallare il dispositivo e installare i driver ufficiali aggiornati Dal sito web del produttore Atheros. Morale: il modulo citato nel BSOD potrebbe essere parte del sottosistema interessato, non la fonte.

  Come installare Arduino IDE su Windows 11 passo dopo passo

Risposta tipica del supporto e passaggi rapidi per gli utenti

In un autentico scambio di supporto, un tecnico ha risposto: "Mi dispiace per l'inconveniente. Potrebbe trattarsi di un problema di driver, di memoria o di antivirus. Aggiorna i driver e, se il problema persiste, esegui la diagnostica della memoria."Si tratta di un consiglio basilare ma valido; tuttavia, se gli errori persistono, è consigliabile procedere ulteriormente con Verifier e l'analisi del dump.

Per gli utenti non tecnici, un protocollo ragionevole potrebbe essere: 1) Controllare gli eventi di sistema, 2) Aggiornare i driver chiave (chipset/rete/grafica), 3) Controllare la RAM con lo strumento integrato, 4) test Boot pulito senza software di terze parti che inserisca hook nel kernel/GUI e 5) utilizzare Verifier sui driver di terze parti se nulla è chiaro.

Le migliori pratiche per gli sviluppatori di driver

Se stai sviluppando e ti imbatti in D1/A, controlla che il la routine in esecuzione non è contrassegnata come paginabile Non chiamare funzioni paginabili durante l'esecuzione a DISPATCH_LEVEL o superiore. Ciò include evitare riferimenti ai dati nelle sezioni paginate e rispettare le restrizioni IRQL per gli helper del kernel descritte nel DDK.

Per sincronizzare i dati condivisi, applicare la regola "accedi sempre ai dati condivisi con lo stesso IRQL elevato" e utilizzare gli spin lock quando appropriato. Sui multiprocessori, l'IRQL da solo non garantisce l'esclusione tra diverse CPU; gli spin lock aumentano l'IRQL (a DISPATCH_LEVEL) e coordinano l'accesso tra i core. Se è necessario operare su registri hardware sensibili, KeSynchronizeExecution ti aiuta a eseguire sezioni critiche con il DIRQL corretto.

Quando il piano richiede l'aumento dell'IRQL, Stati Uniti d'America KeRaiseIrqlToDpcLevel per DISPATCH_LEVEL o KeRaiseIrql accuratamente, salvando l'IRQL precedente e ripristinandolo esattamente con KeLowerIrql. Scendere sotto l'IRQL di input, anche solo per un istante, È un grave errore di sincronizzazione.

Relazione con gli interrupt e l'hardware

IRQL è il meccanismo tramite il quale Windows gli ordini interrompono le priorità e alcune attività interneA livello architetturale è correlato a concetti quali "Interrupt", "Gestore di interrupt" o "Livello di priorità di interrupt" e, sulle piattaforme classiche, con l' Controllore di interrupt programmabile (PIC)In altri sistemi, il controllo della priorità è espresso tramite meccanismi quali spl en Unix; l'idea generale è la stessa: chi può interrompere chi.

Suggerimenti avanzati per il debug

Nei dump in cui lo stack punta a win32kfull!xxxProcessNotifyWinEvent con controllo bug 0xA/0xD1, ispeziona il contesto con .process y .thread (se disponibile), guarda processi come explorer.exe en !process 0 1 e controllare gli overlay e i driver di interazione GUI. Molte volte il problema È una memoria corrotta da una terza parte che emerge su quella rotta.

Non dimenticare di controllare l'IRQL con !irqle contrasto: se sei a DISPATCH_LEVEL (2) e il parametro 3 indica lettura/scrittura/esecuzione su una pagina impaginabile, hai già un indizio sul perché è caduto. Incrocia quell'indizio con ln nel parametro 4 per ottenere la funzione specifica.

capire Che cos'è l'IRQL? e il modo in cui si inserisce nell'esecuzione del kernel aiuta a separare il rumore dai segnali. Se sei un utente, concentrati su driver e hardware (con Verifier, eventi e test di default). Se si sviluppa, è necessario seguire rigorosamente le regole per IRQL, memoria non paginata e sincronizzazione con spin lock. Con gli strumenti giusti (WinDbg, Verifier) ​​e un'attenta lettura dei parametri (1, 3 e 4), Questi controlli dei bug non sono più un mistero e diventano problemi che possono essere affrontati metodicamente.