Windows 中的 IRQL(中斷請求等級)是什麼?它與 BSOD 有何關係?

最後更新: 01/10/2025
作者: 艾薩克
  • IRQL 定義執行優先權並按等級屏蔽中斷,在 DISPATCH 之上它命令 IRQL,而不是執行緒優先權。
  • 很多 藍屏 0xA/0xD1 通常由存取高 IRQL 下的可分頁或無效記憶體以及不正確的位址或可分頁代碼所引起。
  • WinDbg 和 Driver Verifier 是關鍵:使用 !analyze、!irql、ln、.trap、!pool、!address 並檢查參數 1、3 和 4。
  • En 驅動程序,防止高 IRQL 下的頁面錯誤,使用非分頁記憶體和自旋鎖;對於用戶,更新/隔離有問題的驅動程式。

irq

如果您曾經看過藍屏,並顯示類似以下訊息 IRQL_NOT_LESS_OR_EQUAL o DRIVER_IRQL_NOT_LESS_OR_EQUAL你可能遇到過一個在驅動程式領域之外鮮為人知的概念:IRQL(中斷請求等級)。在 Windows,當系統超過某個閾值時,該等級的中斷優先權優先於執行緒優先權,這對穩定性有直接影響。

在接下來的幾行中你會發現 完整指南 以及西班牙的西班牙語關於 IRQL 是什麼,它是如何運作的、為什麼它會觸發藍屏、如何使用 WinDbg 診斷問題,以及無論您是遇到錯誤的用戶還是正在開發內核模式驅動程序,都應該採取哪些措施。讓我們開始吧。

Windows 中的 IRQL(中斷請求等級)是什麼?

在 Windows 中, IRQL 定義 硬件 處理器運作 在任何給定時間。在 Windows 驅動模型 (WDM) 中,以低 IRQL 運行的程式碼可能會被以高 IRQL 執行的程式碼中斷。事實上,在一台多核心電腦上,每個 CPU 可能處於不同的 IRQL,這使得同步變得複雜。

有一條關鍵規則: 當 CPU 以高於 PASSIVE_LEVEL 的 IRQL 執行時,它只能被較高 IRQL 的活動搶佔。這組織了使用者程式碼、核心函數、延遲呼叫程序 (DPC) 和裝置中斷服務例程 (ISR) 之間的共存。

錯誤0x0000000A
相關文章:
錯誤 0x0000000a(藍色畫面死機)。 6 解決方案

等級和優先權:PASSIVE_LEVEL、APC_LEVEL、DISPATCH_LEVEL 和 DIRQL

在一般情況下, 在 x86 上,使用 0 到 31 之間的 IRQL 值;在 x64 上,使用 0 到 15 之間的實際意義是一樣的:IRQL 0(PASSIVE_LEVEL)是執行正常使用者程式碼和許多驅動程式函數的地方; APC 和頁面錯誤 它們通常映射到 IRQL 1(APC_LEVEL);IRQL 2(DISPATCH_LEVEL)包含執行緒調度程序和 DPC。高於 DISPATCH_LEVEL 的級別是為裝置中斷(稱為 DIRQL)和其他內部用途保留的級別,例如 HIGH_LEVEL。

在駕駛員生態系中, 許多常見例程在 DISPATCH_LEVEL 層級運行:例如,DPC 和 StartIo。這種設計確保當其中一個例程正在接觸內部佇列或其他共享資源時,同一層級的另一個例程不會在該 CPU 上搶佔它,因為搶佔規則只允許更高層級的中斷。

在 DISPATCH_LEVEL 和分析/高層次之間有空間 每個設備的硬體中斷(DIRQL)設備的 IRQL 定義了其相對於其他設備的優先權。 WDM 驅動程式在 IRP_MJ_PNP 期間使用 IRP_MN_START_DEVICE 取得此 IRQL。此裝置 IRQL 不是一個全域的固定值,而是與特定中斷線關聯的值。

IRQL 與執行緒優先權

建議不要混淆概念: 執行緒優先權決定調度程序何時搶佔以及哪個執行緒執行IRQL 控制哪些類型的活動可以執行以及哪些中斷被屏蔽。在 DISPATCH_LEVEL 以上,沒有執行緒切換:控制的是 IRQL,而不是執行緒優先權。

  Valve Fremont:洩漏的規格和關鍵線索

IRQL 和分頁:你不該做的事情

提高 IRQL 的一個直接影響是系統 無法處理頁面錯誤黃金法則:在 DISPATCH_LEVEL 或更高層級運行的程式碼不會導致頁面錯誤。實際上,這意味著這些例程及其接觸的數據 必須駐留在非分頁記憶體中此外,某些核心輔助程式會根據 IRQL 限制其使用:例如, KeWaitForSingleObject 只有當您沒有阻塞(零逾時)時才能呼叫 DISPATCH_LEVEL,而對於非零逾時,您需要低於 DISPATCH_LEVEL。

IRQL 的隱式和明確控制

大多數時候, 系統本身以正確的 IRQL 呼叫你的例程 它們應該做什麼。 IRP 的調度例程在 PASSIVE_LEVEL 層級運作(它們可以阻止或呼叫任何輔助程式),StartIo 和 DPC 在 DISPATCH_LEVEL 層級運作以保護共用佇列,ISR 在 DIRQL 層級運作。

如果你需要明確控制它, 您可以使用以下方式提高或降低 IRQL KeRaiseIrql y KeLowerIrql有一個非常常用的快捷方式: KeRaiseIrqlToDpcLevel() 返回之前的 IRQL,並讓你停留在 DISPATCH_LEVEL 層級。重要提示:切勿將 IRQL 降低到低於系統呼叫時的值;打破同步可能會導致非常嚴重的競爭視窗。

與 IRQL 相關的藍色畫面錯誤:IRQL_NOT_LESS_OR_EQUAL 和 DRIVER_IRQL_NOT_LESS_OR_EQUAL

中斷請求

與這些問題相關的兩個經典錯誤檢查是 IRQL_NOT_LESS_OR_EQUAL (0xA) y DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1)兩者都表示嘗試以過高的 IRQL 存取可分頁(或無效)位址。這通常是由於驅動程式使用了錯誤的位址、取消引用了錯誤的指標或在不適當的層級執行了可分頁程式碼。

在具體情況下 DRIVER_IRQL_NOT_LESS_OR_EQUAL (0x000000D1),參數資訊非常豐富:1)引用的記憶體位址;2)當時的IRQL;3)存取類型(0 讀取,1 寫入,2/8 執行);4)引用記憶體的指令位址。使用調試器,您可以使用 ln 參數 4 列出最近的符號並知道正在運行什麼函數.

需要注意的常見原因

除了特定的程式碼之外,還有一些重複的模式。 取消引用指向 DISPATCH_LEVEL 或更高等級的無效指針 這肯定會導致災難。存取該層級的可分頁數據,或執行可分頁程式碼(例如,標記為可分頁的函數),也會觸發錯誤檢查。

其他常見情況包括 呼叫另一個已下載的驅動程式中的函數 (懸空函數指標),或透過無效函數指標間接呼叫。通常,如果系統能夠識別某個模組,您會在藍色畫面上看到它的名稱,並且它也會保存在 KiBugCheckDriver,可透過 dx KiBugCheckDriver 來自 WinDbg。

一個實際的細節: 在大多數 D1/A 中,真正的問題不是 IRQL 本身,而是引用的記憶體位址。這就是為什麼參數 1、3 和 4 對於診斷至關重要。

使用 WinDbg 進行診斷:有用的命令和參數讀取

為了處理這些案件, WinDbg 是關鍵工具,如果 BSOD 提到 NTOSKRNL.EXE 這些資訊提供了許多關於故障是否發生在內核子系統方面的指導。首先 !analyze -v 取得錯誤檢查、堆疊以及(如果幸運的話)涉及的模組的摘要。如果轉儲包含捕獲幀, .trap 讓您處於故障 CPU 的環境。

很多 命令 樁作為 k, kb, kc, kd, kp, kP, kv 它們會向您展示不同程度的回溯細節。 ln 對於參數 4,你可以跳過 指向該記憶體的指令 並取得附近的符號。如果你懷疑優先順序在中斷之前運行, !irql 顯示目標處理器已儲存的 IRQL(例如 DISPATCH_LEVEL)。

  如何在 Windows 上使用 SCRCPY 控制 Android 螢幕

分析參數1的方向, !pool 它會告訴你它是否屬於分頁池; !address y !pte 深入研究該區域的記憶體映射。你可以使用 記憶體顯示命令 檢查嘗試存取的內容。最後, u, ub, uu 允許您圍繞參數 4 的位址進行反彙編。

別忘了 lm t n 列出已載入的模組 y !memusage 對於記憶的一般狀態。如果 KiBugCheckDriver 有東西, dx KiBugCheckDriver 它將傳回 Unicode 模組的名稱:在典型的例子中,「Wdf01000.sys」被視為錯誤檢查期間涉及的驅動程式。

系統工具:驅動程式驗證器、事件檢視器和診斷程序

El 驅動程式驗證程式 即時檢查驅動程式的行為,並在偵測到不正確的資源使用情況(例如池)時強制執行錯誤,引發異常以隔離程式碼中的問題區域。它透過以下方式啟動: verifier命令提示 建議選擇盡可能最小的驅動程式集,以避免增加太多開銷。

如果你不熟悉 WinDbg, 採取基本措施:在事件檢視器中檢查系統日誌,尋找指向特定裝置/驅動程式的錯誤;更新或停用藍色畫面提示的驅動程式;驗證硬體與您的 Windows 版本的相容性;如果您懷疑 RAM 有問題,請使用 Windows 記憶體診斷程式。這些操作雖然簡單,但 他們破獲了大量案件.

真實案例:BSOD 看似隨機

擁有 Windows 10 Pro(AMD Ryzen 5 3400G CPU, GPU NVIDIA GeForce GTX 1660 Ti 和 Gigabyte B450 AORUS PRO WIFI 主機板(16 GB 記憶體)偶爾會出現「IRQL_LESS_OR_NOT_EQUAL」畫面。我已經更新了必要的驅動程式(網路、顯示卡),安裝了所有 Windows 更新,並運行了記憶體工具,但都沒有檢測到任何問題。

在這種情況下, 下一步是使用 WinDbg 分析轉儲 並尋找模式:當它掉落時所涉及的過程(例如, explorer.exe)、圖形介面模組(win32kfull.sys) 以及諸如 xxxProcessNotifyWinEvent 出現在堆疊中。雖然此模組是 Windows 的,但觸發器通常是第三方驅動程式(圖形、輸入、覆蓋、捕獲卡),它以不合適的 IRQL 使用內存,並且故障發生在 win32k.

這裡的實際建議是 暫時停用覆蓋軟體 (擷取、GPU OSD)、激進的軟體週邊驅動程式(具有巨集的滑鼠/鍵盤)以及顯示卡驅動程式的 Beta 版本,並縮小問題範圍。使用驅動程式驗證程式對可疑問題進行分析,有助於縮小問題範圍,並讓問題堆疊更加清晰。

一個非常常見的網路模式:ndis.sys 並不總是罪魁禍首

另一個典型案例: ndis.sys 的螢幕截圖 (Windows 網路層)。在實際的電腦上,系統啟動後會立即崩潰。實際的解決方案是啟動到 安全模式 沒有網路功能時,開啟 設備管理器 並停用“網路適配器”下的適配器以隔離問題。

在那支球隊裡, Realtek PCIe GBE 系列控制器和 Atheros AR5007G。透過停用兩者,檢測到真正的原因是 athrx.sys (Atheros),雖然藍屏提到 ndis.sys轉儲證實了這一點:堆疊通過 ndis!NdisFreeTimerObject 但罪魁禍首是 athrx.sys最終修正為 卸載設備並安裝更新的官方驅動程式 摘自 Atheros 製造商網站。警告:藍屏死機提示的模組可能是受影響子系統的一部分,而非源頭。

  如何在 Windows 11 上逐步安裝 Arduino IDE

典型的支援回應和使用者快速步驟

在一次真誠的支持交流中,一位技術人員回答: 很抱歉造成不便。這可能是驅動程式、記憶體或防毒軟體的問題。請更新您的驅動程序,如果問題仍然存在,請執行記憶體診斷程序。這是基本但有效的建議;但是,如果錯誤仍然存在,最好進一步使用驗證程序和轉儲分析。

對於非技術用戶,合理的協議是: 1)檢查系統事件,2)更新關鍵驅動程式(晶片組/網路/圖形),3)檢查 RAM 使用整合工具,4)測試 開機 無需使用將鉤子插入內核/GUI 的第三方軟體進行清理,5)如果沒有任何明確的地方,請在第三方驅動程式上使用驗證程式。

驅動程式開發人員的最佳實踐

如果你正在開發並偶然發現 D1/A,請檢查 正在運行的例程未標記為可分頁 在 DISPATCH_LEVEL 或更高層級運作時,請勿呼叫可分頁函數。這包括避免引用分頁區中的數據,並遵守 DDK 中描述的內核輔助函數的 IRQL 限制。

要同步共享數據, 應用規則“始終以相同的高 IRQL 存取共享資料” 並在適當的時候使用自旋鎖。在多處理器上,IRQL 本身並不能保證不同 CPU 之間的互斥;自旋鎖會提升 IRQL(至 DISPATCH_LEVEL)並協調不同核心之間的存取。如果需要操作敏感的硬體暫存器, KeSynchronizeExecution 協助您以正確的 DIRQL 執行關鍵部分。

當計劃需要提高 IRQL 時, 美國 KeRaiseIrqlToDpcLevel 對於 DISPATCH_LEVEL 或 KeRaiseIrql 小心,儲存先前的 IRQL 並恢復它 KeLowerIrql. 低於輸入 IRQL,即使只是一瞬間, 這是一個嚴重的同步錯誤.

與中斷和硬體的關係

IRQL 是 Windows 的機制 命令中斷優先權和某些內部任務在架構層面,它與「中斷」、「中斷處理程序」或「中斷優先順序」等概念相關,在經典平台上,它與 可程式中斷控制器(PIC)在其他系統中,優先權控制透過以下機制來表達: spl en Unix的;整體思路是一樣的:誰可以打斷誰。

高級調試技巧

在堆疊指向的轉儲中 win32kfull!xxxProcessNotifyWinEvent 使用錯誤檢查 0xA/0xD1,檢查上下文 .process y .thread (如果可用),請查看以下流程 explorer.exe en !process 0 1 並檢查覆蓋層和 GUI 互動驅動程式。很多時候問題 這是在這條路線上出現的被第三者破壞的記憶.

不要忘記檢查 IRQL !irql,並進行比較: 如果你處於 DISPATCH_LEVEL (2) 且參數 3 表示讀/寫/執行 在可分頁的頁面上,你已經知道為什麼它會掉下來了。用 ln 在參數4中取得具體的函數。

了解 什麼是 IRQL? 以及它如何融入內核執行,有助於區分雜訊和訊號。如果你是用戶,請關注 驅動程式和硬體 (預設使用 Verifier、事件和測試)。如果您進行開發,請嚴格遵循 IRQL、非分頁記憶體和自旋鎖同步的規則。使用正確的工具(WinDbg、Verifier)並仔細閱讀參數(1、3 和 4), 這些錯誤檢查不再是一個謎 而它們成為可以有條不紊地解決的問題。