Czym dokładnie jest IRQL_NOT_LESS_OR_EQUAL? Co to jest IRQL? Jakie rzeczy używają IRQL? Dlaczego musi być mniejszy lub równy? Co sprawiłoby, że nie byłby mniejszy lub równy? Dlaczego system operacyjny nie może się zregenerować, nie będąc mniejszy lub równy? Czy IRQL wpływa tylko na system Windows?
Ten błąd wydaje się dość powszechny . Nie proszę o pomoc, proszę o wyjaśnienie.
Odpowiedzi:
To skomplikowane. ;)
Nie, naprawdę jest.
IRQL to skrót od „Interrupt Request Level”. Jest to liczba od 0 do 31 w systemach Windows x86 i od 0 do 15 w systemach x64. Reprezentuje „ważność” zadania trybu jądra w stosunku do innych zadań trybu jądra.
IRQL to zdefiniowany przez Windows stan procesora - nie procesu lub wątku - który wskazuje systemowi Windows, czy cokolwiek robi ten procesor, może zostać przerwane przez inne zadania. Jeśli nowe zadanie (takie jak procedura usługi przerwań) ma wyższy IRQL niż bieżący IRQL procesora, wówczas tak, może przerwać bieżące zadanie; w przeciwnym razie nie. W systemie wieloprocesorowym każdy procesor ma swój własny IRQL. Obejmuje to „procesory logiczne” utworzone przez hiperwątkowanie.
(Używam słowa „ważność” zamiast „priorytet”, ponieważ „priorytet” w Windows odnosi się do priorytetów wątków, a IRQL są czymś innym. W przeciwieństwie do priorytetów wątków, zadania jądra w tym samym IRQL nie są dzielone na czas, a IRQL nie są podlega automatycznemu wzmocnieniu i rozpadowi).
(Powinienem również wspomnieć, że termin „zadanie jądra” tutaj nie jest oficjalny. Windows tak naprawdę nie nazywa tych rzeczy „zadaniami jądra”, nie są obiektami zarządzanymi, jak np. Procesy i wątki, i nie ma związku z zadaniem x86) gates ”ani do niczego pokazanego w„ Menedżerze zadań ”. Kiedy ja (i inni) używam tego terminu,„ zadanie trybu jądra ”naprawdę obejmuje„ wszystko z określonym początkiem i końcem, które należy wykonać w trybie jądra w IRQL 2 lub powyżej. „Procedura usługi przerwania jest jednym przykładem„ zadania trybu jądra ”, podobnie jak procedura DPC. Ale innym przykładem może być kod w wątku trybu jądra. Takie wątki zaczynają się od IRQL 0, ale jeśli są częścią kodu podnosido IRQL 2 lub nowszego, robi coś, a następnie wraca do poprzedniego IRQL, część kodu o wysokiej IRQL jest jednym z przykładów tego, co nazywam tutaj „zadaniem jądra”. )
Monitor wydajności pokazuje czas spędzony na IRQL 2 jako „% czasu DPC”, a czas na IRQL> 2 jako „% czasu przerwania”, niezależnie od tego, czy faktycznie spędził czas w procedurze DPC lub ISR, czy też był wynikiem podniesienia IRQL z niższa wartość. Każdy z nich jest podzbiorem tego, co PerfMon pokazuje jako „% czasu uprzywilejowanego” - który powinien być oznaczony jako „czas trybu jądra”.
Kiedy zadanie jądra zostanie uruchomione na IRQL 2 lub nowszym, jest uruchamiane do końca, zanim cokolwiek innego na tym samym IRQL zostanie uruchomione na tym samym procesorze. Może to zostać przerwane przez zadanie o wyższej wartości IRQL (które z kolei może zostać przerwane przez zadanie o wyższej wartości IRQL itp.), Ale po zakończeniu zadań o wyższej wartości IRQL kontrola powraca do zadania, które zostało przerwane.
IRQL jest przede wszystkim mechanizmem serializacji . (Wielu mówi „synchronizacja”, ale wolę to słowo, ponieważ dokładniej opisuje wynik.) Jego celem jest pomoc w zagwarantowaniu, że wiele zadań na tym samym CPU, które uzyskują dostęp do niektórych współużytkowanych zasobów - głównie wspólnych struktur danych w przestrzeni jądra systemu operacyjnego - nie mogą sobie przeszkadzać w sposób, który mógłby uszkodzić te struktury.
Na przykład duża część danych w jądrze systemu Windows, szczególnie dane zarządzania pamięcią i dane używane przez program do planowania wątków, są „serializowane” w IRQL 2. Oznacza to, że każde zadanie, które chce zmodyfikować takie dane, musi być uruchomione w IRQL 2, kiedy to robi. Jeśli zadanie o wyższym IRQL próbuje zapisać takie dane, może to spowodować uszkodzenie, ponieważ mogło to przerwać zadanie IRQL 2, które może być w trakcie cyklu odczytu-modyfikacji-zapisu na tych samych danych. Dlatego zadania o wyższym IRQL po prostu nie mogą tego robić.
Zadania o wyższej wartości IRQL są w większości procedurami obsługi przerwań sterowników urządzeń, ponieważ wszystkie przerwania urządzeń występują w IRQL> 2. Obejmuje to przerwanie od układu zegara na płycie głównej, który steruje mierzeniem czasu i aktywnością zależną od czasu w systemie operacyjnym. Jego IRQL jest wyższy niż wszystkich „zwykłych” urządzeń.
IRQL 2 i nowsze są używane do zadań jądra, które nie są wywoływane przez przerwania sprzętowe, ale podczas których nie może wystąpić normalne planowanie wątków - w tym oczekiwanie. Tak więc, gdy procesor osiągnie IRQL 2 lub wyższy, nie może nastąpić zmiana kontekstu wątku na tym procesorze, dopóki IRQL nie spadnie poniżej 2.
Kod trybu użytkownika jest zawsze ustawiony na IRQL 0. Kod trybu jądra może działać na dowolnym IRQL od 0 do dowolnej wartości maksymalnej. IRQL 1 to szczególny przypadek; jest to tylko tryb jądra, ale nie ma wpływu na planowanie, i tak naprawdę jest bardziej stanem wątku niż procesora - jest zapisywany i odtwarzany na przykład podczas przełączania kontekstu wątku.
Aby zachować różne gwarancje serializacji, większość wyjątków (takie jak dzielenie przez zero lub naruszenia dostępu do pamięci, takie jak błędy strony) po prostu nie są obsługiwane w IRQL 2 lub nowszym. (IRQL 2 btw jest powszechnie nazywany „poziomem wysyłki” lub „poziomem DPC”).
A teraz możemy w końcu wyjaśnić ten kod kontroli błędów!
Najczęstszym przypadkiem IRQL_NOT_LESS_OR_EQUAL jest błąd strony (próba dostępu do adresu wirtualnego „nierezydentnego”) lub naruszenie dostępu do pamięci (próba zapisu na stronie tylko do odczytu lub dostęp do strony, która nie jest zdefiniowana w ogóle), który występuje w IRQL 2 lub nowszym.
Jeśli takie wyjątki są zgłaszane w IRQL 0 lub 1, można je „obsłużyć” albo przez kod dostarczony przez system (jak program obsługi błędów stron), albo przez program obsługi wyjątków dostarczony przez programistę. Jednak większości wyjątków nie da się w ogóle obsłużyć, jeśli wystąpiły one na IRQL 2 lub nowszym.
Więc ... kod kontroli błędów oznacza „wyjątek typu, który można obsłużyć tylko w IRQL 0 lub 1, gdy IRQL był w wersji 2 lub wyższej”. tzn. „nie mniej niż 1”. Dziwne sformułowanie, ale tak jest.
Istnieje kilka innych rzeczy, które mogą wywołać tę kontrolę błędów, a wartość, której IRQL nie jest mniejszy lub równy, nie zawsze wynosi 1, ale występują one rzadko. Dokumentacja WinDBG zawiera je.
źródło