- IRQL defineix prioritats dexecució i emmascara interrupcions per nivell, per sobre de DISPATCH mana lIRQL, no la prioritat de fils.
- Els BSOD 0xA/0xD1 solen ser deguts a accessos a memòria paginable o invàlida a IRQL alt ia adreces o codi paginable incorrectes.
- WinDbg i Driver Verifier són claus: utilitza !analyze, !irql, ln, .trap, !pool, !address i examina paràmetres 1, 3 i 4.
- En conductors, evita page faults a IRQL alt, utilitza memòria no paginada i spin locks; en usuari, actualitza/aïlla drivers problemàtics.
Si mai t'ha saltat una pantalla blava amb missatges tipus IRQL_NOT_LESS_OR_EQUAL o DRIVER_IRQL_NOT_LESS_OR_EQUAL, segurament t'hauràs topat amb un concepte poc conegut fora del món dels drivers: l'IRQL (Interrupt Request Level). A Windows, aquest nivell de prioritat d'interrupcions mana més que la prioritat dels fils quan el sistema està per sobre de cert llindar, i això té conseqüències directes en estabilitat.
A les properes línies trobaràs una guia completa i en espanyol d'Espanya sobre què és l'IRQL, com funciona, per què dispara pantalles blaves, com diagnosticar el problema amb WinDbg i què fer tant si ets usuari que pateix la sentència com si desenvolupes drivers en mode kernel. Anem a l'embolic.
Què és l'IRQL (Interrupt Request Level) a Windows?
Al Windows, el IRQL defineix la prioritat de maquinari a la qual opera un processador en un instant donat. Dins del Windows Driver Model (WDM), el codi que s'està executant a un IRQL baix pot ser interromput per codi que corre a un IRQL més alt. De fet, en un mateix equip amb diversos nuclis, cada CPU pot estar en un IRQL diferent, cosa que complica la sincronització.
Hi ha una regla clau: quan una CPU executa un IRQL per sobre de PASSIVE_LEVEL, només pot ser preemptada per activitat a un IRQL encara més gran. Això organitza la convivència entre codi d'usuari, funcions del nucli, trucades diferides (DPC) i rutines de servei d'interrupcions (ISR) de dispositius.
Nivells i prioritats: PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL i DIRQL
En línies generals, a x86 s'usen valors d'IRQL entre 0 i 31; en x64, entre 0 i 15. El significat pràctic és el mateix: IRQL 0 (PASSIVE_LEVEL) és on sexecuta el codi normal dusuari i moltes funcions de driver; APC i fallades de pàgina solen mapejar-se a IRQL 1 (APC_LEVEL); IRQL 2 (DISPATCH_LEVEL) engloba el planificador de fils i les DPC. Per sobre de DISPATCH_LEVEL hi ha nivells reservats per a interrupcions de dispositius (coneguts com a DIRQL) i altres usos interns com HIGH_LEVEL.
A l'ecosistema de drivers, moltes rutines comunes corren a DISPATCH_LEVEL: per exemple, DPC i StartIo. Aquest disseny garanteix que, mentre una està tocant cues internes o altres recursos compartits, una altra rutina al mateix nivell no la preempta en aquesta CPU, perquè la regla de preempció només permet interrompre per nivells més alts.
Entre DISPATCH_LEVEL i els nivells de perfilat/alt hi ha buit per a les interrupcions de maquinari de cada dispositiu (DIRQL). L'IRQL d'un dispositiu defineix la vostra prioritat davant d'altres dispositius. Un driver WDM obté aquest DIRQL durant IRP_MJ_PNP amb IRP_MN_START_DEVICE. Aquest IRQL de dispositiu no és un valor fix global sinó l'associat a la línia d'interrupció concreta.
IRQL davant de prioritat de fil
Convé no confondre conceptes: la prioritat de fil decideix quan el planificador preempta i quin fil executa; l'IRQL controla quin tipus d'activitat podeu executar i quines interrupcions queden emmascarades. Per sobre de DISPATCH_LEVEL no hi ha commutació de fils: allò que mana és l'IRQL, no la prioritat dels fils.
IRQL i paginació: allò que no has de fer
Un efecte immediat daixecar IRQL és que el sistema no pot atendre errors de pàgina. Regla d'or: codi que executa DISPATCH_LEVEL o per sobre no pot provocar page faults. A la pràctica, això implica que aquestes rutines i les dades que toquen han de residir en memòria no paginada. A més, certs helpers del nucli restringeixen el seu ús segons IRQL: per exemple, KeWaitForSingleObject
només es pot invocar DISPATCH_LEVEL si no bloquejaràs (timeout zero) i, per timeouts no nuls, cal estar per sota DISPATCH_LEVEL.
Control implícit i explícit de l'IRQL
La major part del temps, el propi sistema invoca les teves rutines a l'IRQL correcte per al que han de fer. Les dispatch routines per a IRP arriben a PASSIVE_LEVEL (poden bloquejar o trucar a qualsevol helper), StartIo i DPC corren a DISPATCH_LEVEL per protegir cues compartides, i les ISR s'executen a DIRQL.
Si necessites controlar-lo de manera explícita, pots pujar i baixar l'IRQL amb KeRaiseIrql
y KeLowerIrql
. Hi ha una drecera molt usada: KeRaiseIrqlToDpcLevel()
torna l'IRQL anterior i et deixa a DISPATCH_LEVEL. Important: mai baixis IRQL per sota del valor que tenies quan et va trucar el sistema; trencar aquesta sincronia pot obrir finestres de cursa molt serioses.
Errors de pantalla blava lligats a IRQL: IRQL_NOT_LESS_OR_EQUAL i DRIVER_IRQL_NOT_LESS_OR_EQUAL
Dos bug checks clàssics associats a aquests temes són IRQL_NOT_LESS_OR_EQUAL (0xA) y DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1). Tots dos indiquen que es va intentar accedir a una adreça paginable (o invàlida) a un IRQL massa alt. Sol deure's a controladors que usen adreces incorrectes, desreferencien punters dolents o executen codi paginable en nivells inadequats.
En el cas concret de DRIVER_IRQL_NOT_LESS_OR_EQUAL (0x000000D1), els paràmetres són molt informatius: 1) adreça de memòria referenciada; 2) IRQL en aquell moment; 3) tipus d'accés (0 lectura, 1 escriptura, 2/8 execució); 4) direcció de la instrucció que va referir la memòria. Amb el depurador pots fer servir ln
sobre el paràmetre 4 per llistar el símbol més proper i saber quina funció s'estava executant.
Causes habituals que convé tenir al cap
Més enllà del codi específic, hi ha patrons que es repeteixen. Desreferenciar un punter invàlid a DISPATCH_LEVEL o superior és una recepta segura per al desastre. Accedir a dades paginables a aquest nivell, o executar codi paginable (per exemple, una funció marcada com a paginable), també dispara el bug check.
Altres casos freqüents inclouen trucar a una funció en un altre driver que ja va ser descarregat (punter a funció penjant), o invocar indirectament mitjançant un punter de funció invàlid. Sovint, si el sistema aconsegueix identificar un mòdul, veuràs el seu nom a la pròpia pantalla blava i també queda desat a KiBugCheckDriver
, accessible amb dx KiBugCheckDriver
des de WinDbg.
Un detall pràctic: a la majoria de D1/A, el problema real no és l'IRQL en si, sinó la direcció de memòria referenciada. Per això els paràmetres 1, 3 i 4 són or per centrar-ne el diagnòstic.
Diagnòstic amb WinDbg: ordres útils i lectura de paràmetres
Per treballar aquests casos, WinDbg és l'eina clau, i si la BSOD esmenta ntoskrnl.exe aquesta dada orienta molt sobre si la fallada és de subsistema kernel. Comença per !analyze -v
per obtenir un resum del bug check, l'stack i, si hi ha sort, el mòdul implicat. Si el bolcat inclou un marc de captura, .trap
et situa en el context de CPU que va fallar.
Els ordres de pila com k
, kb
, kc
, kd
, kp
, kP
, kv
us mostren diferents nivells de detall del backtrace. Amb ln
sobre el paràmetre 4 pots saltar a la instrucció que va referir la memòria i obtenir el símbol proper. I si sospites del nivell de prioritat en execució abans de la interrupció, !irql
us mostra l'IRQL desat per al processador objectiu (per exemple, DISPATCH_LEVEL).
Per analitzar la direcció del paràmetre 1, !pool
et dirà si pertany a pool paginat; !address
y !pte
aprofundeixen en el mapatge de memòria d'aquesta zona. Pots fer servir les ordres de visualització de memòria per inspeccionar el contingut a què es va intentar accedir. Finalment, u
, ub
, uu
et permeten desassemblar al voltant de la direcció del paràmetre 4.
No oblidis lm t n
per llistar mòduls carregats y !memusage
per a l'estat general de memòria. Si KiBugCheckDriver
té alguna cosa, dx KiBugCheckDriver
et tornarà el nom del mòdul Unicode: en un exemple típic es veia "Wdf01000.sys" com a driver involucrat durant el bug check.
Eines del sistema: Driver Verifier, Visor d'esdeveniments i diagnòstics
El Comprovador de controladors (Driver Verifier) examina en temps real el comportament dels drivers i força errors quan detecta usos incorrectes de recursos (com el pool), provocant una excepció per aïllar la zona problemàtica del codi. Es llança amb verifier
des de la símbol de sistema i convé seleccionar el menor conjunt de controladors possibles per no afegir gaire sobrecàrrega.
Si no et veus amb WinDbg, aplica mesures bàsiques: revisa el registre del sistema al Visor d'esdeveniments cercant errors que apuntin a un dispositiu/driver concret; actualitza o desactiva el controlador esmentat per la pantalla blava; verifica la compatibilitat del maquinari amb la teva versió de Windows i fes servir el Diagnòstic de memòria de Windows si sospites de RAM. Aquestes accions, encara que senzilles, resolen una gran quantitat de casos.
Casos reals: quan els BSOD semblen aleatoris
Un usuari amb Windows 10 Pro (CPU AMD Ryzen 5 3400G, GPU NVIDIA GeForce GTX 1660 Ti i placa Gigabyte B450 AORUS PRO WIFI, 16 GB de RAM) patia cops de pantalla «IRQL_LESS_OR_NOT_EQUAL» de forma intermitent. Ja havia actualitzat drivers essencials (xarxa, gràfica), instal·lat totes les actualitzacions de Windows i passat l'eina de memòria, sense detectar problemes.
En escenaris així, el següent és analitzar bolcats amb WinDbg i cercar patrons: processos implicats quan cau (per exemple, explorer.exe
), mòduls d'interfície gràfica (win32kfull.sys
) i funcions com xxxProcessNotifyWinEvent
apareixent a l'stack. Encara que aquest mòdul és de Windows, moltes vegades el detonant és un tercer controlador (gràfica, input, superposició/overlay, capturadores) que trepitja memòria a un IRQL inadequat i la fallada aflora dins de win32k
.
La recomanació pràctica aquí és desactivar temporalment programari d'overlay (captura, OSD de GPU), controladors de perifèrics amb programari agressiu (ratolins/teclats amb macros) i versions beta de drivers gràfics, i anar acotant. Driver Verifier sobre sospitosos pot ajudar a que el problema caigui amb un stack més clar.
Un patró molt comú en xarxa: ndis.sys no sempre és el culpable
Un altre cas típic: pantalla amb ndis.sys (la capa de xarxa de Windows). En un equip real, el sistema queia només arrencar. La solució pràctica va ser iniciar a Mode segur sense funcions de xarxa, obrir el Administrador de dispositius i desactivar adaptadors sota «Adaptadors de xarxa» per aïllar el problema.
En aquest equip convivien un Realtek PCIe GBE Family Controller i un Atheros AR5007G. Desactivant l'un i l'altre, es va detectar que la causa real era el athrx.sys
(Atheros), encara que la pantalla blava esmentés ndis.sys
. El bolcat així ho confirmava: l'stack passava per ndis!NdisFreeTimerObject
però el mòdul culpable era athrx.sys
. La correcció definitiva va ser desinstal·lar el dispositiu i posar drivers oficials actualitzats des del lloc del fabricant d'Atheros. Moral: el mòdul esmentat a la BSOD pot ser part del subsistema que en pateix les conseqüències, no l'origen.
Resposta típica de suport i passos ràpids per a usuaris
En un intercanvi genuí de suport, un tècnic contestava: «Lamento l'inconvenient, és possible una fallada de drivers, memòria o antivirus; actualitza drivers i, si es repeteix, executa el diagnòstic de memòria». És un consell bàsic però vàlid; no obstant això, si els errors persisteixen, convé anar més enllà amb Verifier i anàlisi de consagrats.
Per a usuaris no tècnics, un protocol raonable seria: 1) revisar esdeveniments del sistema; 2) actualitzar controladors claus (chipset/xarxa/gràfica); 3) comprovar RAM amb l'eina integrada, 4) provar arrencada net sense programari de tercers que inseriu hooks en kernel/GUI, i 5) utilitzar Verifier sobre drivers de tercers si no apareix res clar.
Bones pràctiques per a desenvolupadors de drivers
Si estàs desenvolupant i ensopegues amb D1/A, verifica que la rutina en execució no estigui marcada com a paginable ni truqueu a funcions paginables mentre corre a DISPATCH_LEVEL o superior. Això inclou evitar referències a dades en seccions paginades i respectar les restriccions d'IRQL dels helpers del nucli descrites al DDK.
Per sincronitzar dades compartides, aplica la regla «accediu sempre a les dades compartides al mateix IRQL elevat» i utilitza spin locks quan correspongui. A multiprocessador, l'IRQL per si sol no garanteix exclusió entre CPUs diferents; els spin locks eleven IRQL (a DISPATCH_LEVEL) i coordinen accés entre nuclis. Si necessites operar sobre registres de maquinari sensibles, KeSynchronizeExecution
t'ajuda a executar seccions crítiques al DIRQL adequat.
Quan el pla requereix elevar IRQL, EUA KeRaiseIrqlToDpcLevel
per a DISPATCH_LEVEL o KeRaiseIrql
amb cura, guardant l'IRQL anterior i restaurant-lo exactament amb KeLowerIrql
. Baixeu per sota de l'IRQL d'entrada, encara que sigui «un instant», és un error greu de sincronització.
Relació amb interrupcions i maquinari
IRQL és el mecanisme amb què Windows ordena les prioritats d'interrupció i certes tasques internes. A nivell d'arquitectura, es relaciona amb conceptes com Interrupt, Interrupt handler o Interrupt priority level i, en plataformes clàssiques, amb el Controlador d'interrupció programable (PIC). En altres sistemes, el control de prioritats s'expressa via mecanismes com sPL en Unix; la idea general és la mateixa: qui pot interrompre qui.
Consells avançats de depuració
En dumps on l'stack apunta a win32kfull!xxxProcessNotifyWinEvent
amb bug check 0xA/0xD1, inspecciona context amb .process
y .thread
(si estan disponibles), mira processos com explorer.exe
en !process 0 1
i comprova overlays i drivers dinteracció amb la GUI. Moltes vegades el problema és memòria corrompuda per un tercer que aflora en aquesta ruta.
No oblidis verificar l'IRQL amb !irql
, i contrastar: si estàs a DISPATCH_LEVEL (2) i el paràmetre 3 indica lectura/escriptura/execució sobre una pàgina paginable, ja tens una pista de per què ha caigut. Creua aquesta pista amb ln
al paràmetre 4 per obtenir la funció concreta.
Entendre què és l'IRQL i com encaixa en l'execució del nucli ajuda a separar el soroll dels senyals. Si ets usuari, centra't en drivers i maquinari (amb Verifier, esdeveniments i proves per descart). Si desenvolupes, respecta rigorosament les regles d'IRQL, memòria no paginada i sincronització amb spin locks. Amb les eines adequades (WinDbg, Verifier) i una lectura curosa de paràmetres (1, 3 i 4), aquests bug checks deixen de ser un misteri i passen a ser problemes abordables amb mètode.
Redactor apassionat del món dels bytes i la tecnologia en general. M'encanta compartir els meus coneixements a través de l'escriptura, i això és el que faré en aquest bloc, mostrar tot el més interessant sobre gadgets, programari, maquinari, tendències tecnològiques, i més. El meu objectiu és ajudar-te a navegar pel món digital de forma senzilla i entretinguda.