- IRQL definiuje priorytety wykonywania i maskuje przerwania według poziomu; powyżej DISPATCH wydaje polecenia IRQL, a nie priorytet wątku.
- L BSOD Błędy 0xA/0xD1 są zwykle spowodowane dostępem do pamięci stronicowanej lub nieprawidłowej przy wysokim IRQL i nieprawidłowych adresach lub kodzie stronicowanym.
- Kluczowe są WinDbg i Driver Verifier: użyj !analyze, !irql, ln, .trap, !pool, !address i sprawdź parametry 1, 3 i 4.
- En sterowniki, zapobiega błędom stronicowania przy wysokim IRQL, wykorzystuje pamięć niestronicowaną i blokady spinowe; dla użytkownika aktualizuje/izoluje problematyczne sterowniki.
Jeśli kiedykolwiek widziałeś niebieski ekran z komunikatami takimi jak IRQL_NOT_LESS_OR_EQUAL o STEROWNIK_IRQL_NIE_MNIEJSZY_LUB_RÓWNY, prawdopodobnie natknąłeś się na koncepcję, która jest mało znana poza światem sterowników: IRQL (poziom żądania przerwania). Windows, ten poziom priorytetu przerwania ma pierwszeństwo przed priorytetem wątku, gdy system przekracza pewien próg, a to ma bezpośrednie konsekwencje dla stabilności.
W kolejnych linijkach znajdziesz u kompletny przewodnik i po hiszpańsku z Hiszpanii o tym, czym jest IRQL i jak działaDlaczego powoduje niebieskie ekrany, jak zdiagnozować problem z WinDbg i co zrobić, niezależnie od tego, czy jesteś użytkownikiem doświadczającym błędu, czy instalującym sterowniki trybu jądra. Przejdźmy do konkretów.
Czym jest IRQL (Interrupt Request Level) w systemie Windows?
W systemie Windows plik IRQL definiuje priorytet sprzęt komputerowy w którym pracuje procesor w dowolnym momencie. W ramach modelu sterowników systemu Windows (WDM) kod działający z niskim IRQL może zostać przerwany przez kod działający z wyższym IRQL. W rzeczywistości na jednym komputerze wielordzeniowym każdy procesor może mieć inny IRQL, co komplikuje synchronizację.
Istnieje jedna kluczowa zasada: Gdy procesor działa na poziomie IRQL wyższym niż PASSIVE_LEVEL, może zostać wywłaszczony wyłącznie przez aktywność na jeszcze wyższym poziomie IRQL.Organizuje współistnienie kodu użytkownika, funkcji jądra, odroczonych wywołań (DPC) i procedur obsługi przerwań urządzeń (ISR).
Poziomy i priorytety: PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL i DIRQL
Ogólnie W architekturze x86 używane są wartości IRQL z przedziału od 0 do 31, w architekturze x64 z przedziału od 0 do 15Praktyczne znaczenie jest takie samo: IRQL 0 (PASSIVE_LEVEL) to miejsce, w którym wykonywany jest normalny kod użytkownika i wiele funkcji sterownika; APC i błędy stronicowania Zazwyczaj są one mapowane na IRQL 1 (APC_LEVEL); IRQL 2 (DISPATCH_LEVEL) obejmuje harmonogram wątków i DPC. Powyżej DISPATCH_LEVEL znajdują się poziomy zarezerwowane dla przerwań urządzeń (znane jako DIRQL) i innych zastosowań wewnętrznych, takich jak HIGH_LEVEL.
W ekosystemie kierowców Wiele typowych procedur jest uruchamianych na poziomie WYSYŁANIA: na przykład DPC i StartIo. Taka konstrukcja gwarantuje, że gdy jedna z nich obsługuje kolejki wewnętrzne lub inne współdzielone zasoby, inna procedura na tym samym poziomie nie wywłaszcza jej na tym samym procesorze, ponieważ reguła wywłaszczania zezwala tylko na przerwania na wyższych poziomach.
Pomiędzy poziomem DISPATCH_LEVEL a poziomami profilowania/wysokimi jest miejsce na przerwania sprzętowe każdego urządzenia (DIRQL)IRQL urządzenia definiuje jego priorytet nad innymi urządzeniami. Sterownik WDM uzyskuje ten IRQL podczas IRP_MJ_PNP z IRP_MN_START_DEVICE. Ten IRQL urządzenia nie jest globalną, stałą wartością, lecz wartością powiązaną z konkretną linią przerwania.
IRQL a priorytet wątków
Zaleca się nie mylić pojęć: Priorytet wątku decyduje, kiedy harmonogram ma pierwszeństwo i który wątek ma zostać wykonanyIRQL kontroluje, jaki typ aktywności może zostać wykonany i które przerwania są maskowane. Powyżej poziomu DISPATCH_LEVEL nie ma przełączania wątków: to IRQL kontroluje, a nie priorytet wątku.
IRQL i stronicowanie: czego nie należy robić
Bezpośrednim skutkiem podniesienia IRQL jest to, że system nie może obsłużyć błędów stronZłota zasada: kod działający na poziomie DISPATCH_LEVEL lub wyższym nie może powodować błędów stron. W praktyce oznacza to, że te procedury i dane, których dotyczą, musi znajdować się w pamięci niestronicowanejPonadto niektóre programy pomocnicze jądra ograniczają swoje użycie na podstawie IRQL: na przykład, KeWaitForSingleObject
Funkcję DISPATCH_LEVEL można wywołać tylko wtedy, gdy nie blokujesz (limit czasu wynosi zero), a w przypadku limitów czasu innych niż zero, musisz znajdować się poniżej DISPATCH_LEVEL.
Kontrola jawna i niejawna IRQL
W większości przypadków system sam wywołuje Twoje procedury w odpowiednim IRQL co powinny robić. Procedury dyspozytorskie dla IRP działają na poziomie PASSIVE_LEVEL (mogą blokować lub wywoływać dowolny program pomocniczy), StartIo i DPC działają na poziomie DISPATCH_LEVEL, aby chronić współdzielone kolejki, a procedury ISR działają na poziomie DIRQL.
Jeśli chcesz to kontrolować jawnie, Możesz podnieść i obniżyć IRQL za pomocą KeRaiseIrql
y KeLowerIrql
Istnieje bardzo często używany skrót: KeRaiseIrqlToDpcLevel()
Zwraca poprzedni IRQL i pozostawia Cię na poziomie DISPATCH_LEVEL. Ważne: Nigdy nie obniżaj IRQL poniżej wartości, która była w momencie wywołania przez system; zerwanie synchronizacji może spowodować poważne problemy z uruchomieniem systemu.
Błędy niebieskiego ekranu związane z IRQL: IRQL_NOT_LESS_OR_EQUAL i DRIVER_IRQL_NOT_LESS_OR_EQUAL
Dwiema klasycznymi kontrolami błędów związanymi z tymi problemami są: IRQL_NIE_MNIEJ_LUB_RÓWNE (0xA) y STEROWNIK_IRQL_NIE_MNIEJSZY_LUB_RÓWNY (0xD1)Oba wskazują na próbę dostępu do stronicowanego (lub nieprawidłowego) adresu o zbyt wysokim IRQL. Zazwyczaj jest to spowodowane przez sterowniki używające nieprawidłowych adresów, dereferencjonujące błędne wskaźniki lub wykonujące stronicowany kod na niewłaściwych poziomach.
W konkretnym przypadku STEROWNIK_IRQL_NIE_MNIEJSZY_LUB_RÓWNY (0x000000D1)Parametry są bardzo pouczające: 1) adres pamięci, do której się odwołuje; 2) aktualny IRQL; 3) typ dostępu (0 odczyt, 1 zapis, 2/8 wykonanie); 4) adres instrukcji, która odwoływała się do pamięci. Za pomocą debugera można użyć ln
na parametrze 4 dla wypisz najbliższy symbol i dowiedz się, jaka funkcja była uruchomiona.
Typowe przyczyny, o których należy pamiętać
Oprócz konkretnego kodu istnieją wzorce, które się powtarzają. Dereferencjonowanie nieprawidłowego wskaźnika do poziomu DISPATCH_LEVEL lub wyższego To pewny przepis na katastrofę. Dostęp do danych stronicowanych na tym poziomie lub wykonanie stronicowanego kodu (np. funkcji oznaczonej jako stronicowana) również uruchamia sprawdzanie błędów.
Inne typowe przypadki obejmują: wywołaj funkcję w innym sterowniku, który został już pobrany (wiszący wskaźnik funkcji) lub wywołany pośrednio przez nieprawidłowy wskaźnik funkcji. Często, jeśli system jest w stanie zidentyfikować moduł, jego nazwa jest wyświetlana na niebieskim ekranie, a także zapisywana w KiBugCheckDriver
, dostępny z dx KiBugCheckDriver
z WinDbg.
Praktyczny szczegół: W większości przypadków D1/A prawdziwym problemem nie jest sam IRQL, ale raczej adres pamięci, do którego się odwołuje. Dlatego parametry 1, 3 i 4 są kluczowe dla ukierunkowania diagnostyki.
Diagnostyka za pomocą WinDbg: przydatne polecenia i odczyt parametrów
Aby pracować nad tymi przypadkami, WinDbg jest kluczowym narzędziem, a jeśli BSOD wspomina ntoskrnl.exe Informacje te dostarczają wielu wskazówek, czy błąd leży w podsystemie jądra. Zacznij od !analyze -v
aby uzyskać podsumowanie kontroli błędów, stosu i, jeśli masz szczęście, modułu, którego to dotyczy. Jeśli zrzut zawiera ramkę przechwytywania, .trap
umieszcza Cię w kontekście uszkodzonego procesora.
L polecenia stosu jako k
, kb
, kc
, kd
, kp
, kP
, kv
Pokazują różne poziomy szczegółowości śledzenia wstecznego. ln
w parametrze 4 możesz pominąć do instrukcji odwołującej się do pamięci i pobierz pobliski symbol. A jeśli podejrzewasz, że poziom priorytetu działa przed przerwaniem, !irql
pokazuje zapisany IRQL dla procesora docelowego (np. DISPATCH_LEVEL).
Aby przeanalizować kierunek parametru 1, !pool
Powie Ci, czy należy do puli stronicowanej; !address
y !pte
zagłębić się w mapowanie pamięci tego obszaru. Możesz użyć polecenia wyświetlania pamięci aby sprawdzić zawartość, do której próbowano uzyskać dostęp. Na koniec, u
, ub
, uu
pozwalają na demontaż adresu parametru 4.
Nie zapomnij lm t n
aby wyświetlić listę załadowanych modułów y !memusage
dla ogólnego stanu pamięci. Jeśli KiBugCheckDriver
ma coś, dx KiBugCheckDriver
Zwrócona zostanie nazwa modułu Unicode: w typowym przykładzie „Wdf01000.sys” został rozpoznany jako sterownik objęty kontrolą błędów.
Narzędzia systemowe: Driver Verifier, Podgląd zdarzeń i Diagnostyka
El Weryfikator sterowników Analizuje zachowanie sterowników w czasie rzeczywistym i wymusza błędy w przypadku wykrycia nieprawidłowego wykorzystania zasobów (takich jak pula), zgłaszając wyjątek w celu wyizolowania problematycznego obszaru kodu. Jest uruchamiany z verifier
z wiersz polecenia Zaleca się wybranie najmniejszego zestawu sterowników, jaki jest możliwy, aby uniknąć dodawania zbyt dużego obciążenia.
Jeśli nie widzisz siebie z WinDbg, zastosować podstawowe środkiSprawdź dziennik systemowy w Podglądzie zdarzeń pod kątem błędów wskazujących na konkretne urządzenie/sterownik; zaktualizuj lub wyłącz sterownik wskazany na niebieskim ekranie; sprawdź zgodność sprzętu z posiadaną wersją systemu Windows; i skorzystaj z narzędzia Diagnostyka pamięci systemu Windows, jeśli podejrzewasz problem z pamięcią RAM. Te czynności, choć proste, rozwiązują dużą liczbę przypadków.
Przykłady z życia wzięte: Kiedy BSOD-y wydają się losowe
Użytkownik z systemem Windows 10 Pro (procesor AMD Ryzen 5 3400G, GPU NVIDIA Karta graficzna GeForce GTX 1660 Ti i Gigabyte B450 AORUS PRO WIFI, 16 GB pamięci RAM) doświadczał sporadycznych ekranów „IRQL_LESS_OR_NOT_EQUAL”. Zaktualizowałem już niezbędne sterowniki (sieciowe i graficzne), zainstalowałem wszystkie aktualizacje systemu Windows i uruchomiłem narzędzie do zarządzania pamięcią, ale nie wykryłem żadnych problemów.
W takich scenariuszach, Następnym krokiem jest analiza zrzutów za pomocą WinDbg i poszukaj wzorców: procesów zachodzących w momencie upadku (na przykład, explorer.exe
), moduły interfejsu graficznego (win32kfull.sys
) i funkcje takie jak xxxProcessNotifyWinEvent
pojawiające się w stosie. Chociaż ten moduł to Windows, wyzwalaczem jest często sterownik innej firmy (karty graficzne, wejściowe, nakładkowe, przechwytujące), który wykorzystuje pamięć z niewłaściwym IRQL, a błąd pojawia się w win32k
.
Praktyczną rekomendacją w tym przypadku jest tymczasowo wyłącz oprogramowanie nakładkowe (przechwytywanie, OSD GPU), agresywne sterowniki peryferyjne oprogramowania (myszy/klawiatury z makrami) oraz wersje beta sterowników graficznych i zawęż problem. Użycie Driver Verifier na podejrzanych może pomóc zawęzić problem dzięki bardziej przejrzystemu stosowi.
Bardzo powszechny problem sieciowy: ndis.sys nie zawsze jest winowajcą
Inny typowy przypadek: zrzut ekranu z ndis.sys (warstwa sieciowa Windows). Na prawdziwym komputerze system ulegałby awarii natychmiast po uruchomieniu. Praktycznym rozwiązaniem było uruchomienie Tryb awaryjny bez funkcji sieciowych otwórz Menedżer urządzeń i wyłącz adaptery w zakładce „Adaptery sieciowe”, aby zlokalizować problem.
W tej drużynie był Kontroler rodziny Realtek PCIe GBE i Atheros AR5007G. Dezaktywując oba, wykryto, że prawdziwą przyczyną jest athrx.sys
(Atheros), chociaż niebieski ekran o tym wspominał ndis.sys
Zrzut potwierdził to: stos przeszedł przez ndis!NdisFreeTimerObject
ale modułem winnym był athrx.sys
Ostateczna korekta była odinstaluj urządzenie i zainstaluj zaktualizowane oficjalne sterowniki Ze strony internetowej producenta Atheros. Morał: Moduł wymieniony w BSOD może być częścią podsystemu, którego dotyczy problem, a nie jego źródłem.
Typowa odpowiedź pomocy technicznej i szybkie kroki dla użytkowników
W ramach szczerej wymiany zdań, technik odpowiedział: Przepraszamy za niedogodności. Problem może dotyczyć sterownika, pamięci lub programu antywirusowego. Prosimy o aktualizację sterowników i, jeśli problem będzie się powtarzał, przeprowadzenie diagnostyki pamięci.Jest to podstawowa, ale słuszna rada. Jeśli jednak błędy nadal występują, warto kontynuować pracę z Verifierem i wykonać analizę zrzutu.
Dla użytkowników nietechnicznych rozsądnym protokołem byłoby: 1) Sprawdź zdarzenia systemowe, 2) Zaktualizuj kluczowe sterowniki (chipset/sieć/grafika), 3) Sprawdź pamięć RAM za pomocą zintegrowanego narzędzia, 4) test boot wyczyść bez oprogramowania firm trzecich, które wstawia haki do jądra/GUI i 5) użyj Verifiera na sterownikach firm trzecich, jeśli nic nie jest jasne.
Najlepsze praktyki dla programistów sterowników
Jeśli rozwijasz się i natkniesz się na D1/A, sprawdź, czy rutyna robocza nie jest oznaczona jako stronicowalna Nie wywołuj funkcji stronicowanych podczas działania na poziomie DISPATCH_LEVEL lub wyższym. Obejmuje to unikanie odniesień do danych w sekcjach stronicowanych oraz przestrzeganie ograniczeń IRQL dla funkcji pomocniczych jądra opisanych w pakiecie DDK.
Aby synchronizować współdzielone dane, zastosuj regułę „zawsze uzyskuj dostęp do współdzielonych danych z tym samym wysokim IRQL” i stosuj blokady spinowe w razie potrzeby. W systemach wieloprocesorowych sam IRQL nie gwarantuje wykluczenia między różnymi procesorami; blokady spinowe podnoszą poziom IRQL (do poziomu DISPATCH_LEVEL) i koordynują dostęp między rdzeniami. Jeśli musisz operować na wrażliwych rejestrach sprzętowych, KeSynchronizeExecution
pomaga wykonać krytyczne sekcje przy użyciu prawidłowego języka DIRQL.
Gdy plan wymaga podniesienia IRQL, USA KeRaiseIrqlToDpcLevel
dla POZIOMU_WYSYŁANIA lub KeRaiseIrql
ostrożnie, zapisując poprzedni IRQL i przywracając go dokładnie z KeLowerIrql
. Zejdź poniżej wejściowego IRQL, nawet na chwilę, To poważny błąd synchronizacji.
Związek z przerwaniami i sprzętem
IRQL to mechanizm, dzięki któremu system Windows zamówienia zakłócają priorytety i niektóre zadania wewnętrzneNa poziomie architektonicznym jest ona powiązana z takimi koncepcjami jak „Przerwanie”, „Obsługa przerwań” czy „Poziom priorytetu przerwań”, a na klasycznych platformach z Programowalny kontroler przerwań (PIC)W innych systemach kontrola priorytetów wyrażana jest za pomocą mechanizmów takich jak: spl en Unix; ogólna idea jest ta sama: kto może komu przeszkadzać.
Zaawansowane wskazówki dotyczące debugowania
W zrzutach, na które wskazuje stos win32kfull!xxxProcessNotifyWinEvent
z kontrolą błędów 0xA/0xD1, sprawdź kontekst za pomocą .process
y .thread
(jeśli dostępne), spójrz na procesy takie jak explorer.exe
en !process 0 1
i sprawdź nakładki oraz sterowniki interakcji GUI. Często problem To pamięć uszkodzona przez osobę trzecią, która pojawia się na tej trasie.
Nie zapomnij sprawdzić IRQL za pomocą !irql
i kontrast: jeśli jesteś na poziomie DISPATCH_LEVEL (2) i parametr 3 wskazuje odczyt/zapis/wykonanie Na stronie stronicowanej masz już wskazówkę, dlaczego spadła. Skrzyżuj tę wskazówkę z ln
w parametrze 4, aby uzyskać określoną funkcję.
zrozumieć Czym jest IRQL? i to, jak wpisuje się w wykonywanie jądra, pomaga oddzielić szum od sygnałów. Jeśli jesteś użytkownikiem, skup się na sterowniki i sprzęt (z weryfikatorem, zdarzeniami i testami domyślnie). Jeśli tworzysz oprogramowanie, ściśle przestrzegaj zasad dotyczących IRQL, pamięci niestronicowanej i synchronizacji z blokadami spinowymi. Z odpowiednimi narzędziami (WinDbg, Verifier) i uważnym odczytaniem parametrów (1, 3 i 4), Kontrole błędów nie są już tajemnicą. i stają się problemami, które można rozwiązywać metodycznie.
Pisarz z pasją zajmujący się światem bajtów i technologii w ogóle. Uwielbiam dzielić się swoją wiedzą poprzez pisanie i właśnie to będę robić na tym blogu, pokazywać Ci wszystkie najciekawsze rzeczy o gadżetach, oprogramowaniu, sprzęcie, trendach technologicznych i nie tylko. Moim celem jest pomóc Ci poruszać się po cyfrowym świecie w prosty i zabawny sposób.