IRQL_NOT_LESS_OR_EQUAL이 정확히 무엇인가요? IRQL이란 무엇입니까? IRQL을 사용하는 것은 무엇입니까? 왜 작거나 같아야 합니까? 무엇이 더 작거나 같지 않게 만들까요? OS가 작거나 같지 않은 경우 왜 복구할 수 없나요? IRQL은 Windows에만 영향을 미치나요?
이 오류는꽤 흔한. 나는 도움을 요청하는 것이 아니라 설명을 요청하는 것입니다.
답변1
복잡해요. ;)
아니요, 정말 그렇습니다.
IRQL은 "인터럽트 요청 수준"을 나타냅니다. Windows x86 시스템에서는 0부터 31까지, x64 시스템에서는 0부터 15까지의 숫자입니다. 이는 다른 커널 모드 작업에 비해 커널 모드 작업의 "중요성"을 나타냅니다.
IRQL은 프로세스나 스레드가 아닌 Windows에서 정의한 프로세서 상태로, 해당 프로세서가 수행 중인 모든 작업이 다른 작업에 의해 중단될 수 있는지 여부를 Windows에 나타냅니다. 새 작업(예: 인터럽트 서비스 루틴)이 프로세서의 현재 IRQL보다 높은 IRQL을 갖는 경우 그렇습니다. 현재 작업을 중단할 수 있습니다. 그렇지 않으면 아니오. 다중 프로세서 시스템에서는 각 프로세서마다 고유한 IRQL이 있습니다. 여기에는 하이퍼스레딩으로 생성된 "논리 프로세서"가 포함됩니다.
( Windows의 "우선순위"는 스레드 우선순위를 나타내고 IRQL은 뭔가 다르기 때문에 "우선순위" 대신 "중요성"이라는 단어를 사용합니다. 스레드 우선순위와 달리 동일한 IRQL의 커널 작업은 시간 분할되지 않으며 IRQL은 자동 부스트 및 감쇠 대상이 아닙니다.
( 여기서 "커널 작업"이라는 용어는 공식적인 것이 아니라는 점도 언급해야 합니다. Windows는 실제로 이러한 것을 "커널 작업"이라고 부르지 않으며 프로세스 및 스레드와 같이 관리되는 개체가 아니며 x86 "작업"과는 아무런 관련이 없습니다. 게이트"도 아니고 "작업 관리자"에 표시된 것도 아닙니다. 나(및 다른 사람들)가 여기서 용어를 사용함에 따라 "커널 모드 작업"은 실제로 "IRQL 2 또는 커널 모드에서 수행되어야 하는 정의된 시작과 끝이 있는 모든 작업"을 포함합니다. 위의." 인터럽트 서비스 루틴은 "커널 모드 작업"의 한 예입니다. DPC 루틴도 마찬가지입니다. 그러나 또 다른 예는 커널 모드 스레드의 코드일 수 있습니다. 이러한 스레드는 IRQL 0에서 시작하지만 코드의 일부인 경우인상IRQL 2 이상으로 전환하고 어떤 작업을 수행한 다음 이전 IRQL로 돌아갑니다. 코드의 IRQL이 높은 부분은 여기서 "커널 작업"이라고 부르는 것의 한 예입니다. )
성능 모니터는 시간이 실제로 DPC 루틴이나 ISR에서 소비되었는지 또는 IRQL을 높인 결과인지에 관계없이 IRQL 2에서 소비된 시간을 "% DPC 시간"으로, IRQL > 2에서 소비된 시간을 "% 인터럽트 시간"으로 표시합니다. 더 낮은 값. 각각은 PerfMon이 "% 특권 시간"으로 표시하는 것의 하위 집합입니다. 이는 "커널 모드 시간"이라는 레이블이 지정되어야 합니다.
커널 작업이 IRQL 2 이상에서 시작되면 다른 작업보다 먼저 완료될 때까지 실행됩니다.같은IRQL은 동일한 프로세서에서 시작됩니다. 더 높은 IRQL 작업에 의해 중단될 수 있지만(이는 다시 더 높은 IRQL 작업에 의해 중단될 수 있음) 더 높은 IRQL 작업이 완료되면 제어는 중단된 작업으로 돌아갑니다.
IRQL은 주로직렬화기구. (많은 사람들이 "동기화"라고 말하지만 결과를 더 정확하게 설명하기 때문에 이 단어를 선호합니다.) 그 목적은 특정 공유 리소스(주로 OS 커널 공간의 공유 데이터 구조)에 액세스하는 동일한 CPU의 여러 작업을 보장하는 것입니다. 이러한 구조를 손상시킬 수 있는 방식으로 서로를 방해하는 것은 허용되지 않습니다.
예를 들어, Windows 커널에 있는 많은 양의 데이터, 특히 메모리 관리 데이터와 스레드 스케줄러에서 사용하는 데이터는"직렬화"IRQL 2에서. 이는 그러한 데이터를 수정하려는 모든 작업이 그렇게 할 때 IRQL 2에서 실행되어야 함을 의미합니다. 더 높은 IRQL 작업이 그러한 데이터를 쓰려고 시도하면 손상이 발생할 수 있습니다. 동일한 데이터에 대한 읽기-수정-쓰기 주기 중간에 있을 수 있는 IRQL 2 작업이 중단되었을 수 있기 때문입니다. 따라서 더 높은 IRQL 작업은 그렇게 하는 것이 허용되지 않습니다.
IRQL이 높은 작업은 대부분 장치 드라이버의 인터럽트 서비스 루틴입니다. 왜냐하면 모든 장치의 인터럽트는 IRQL > 2에서 발생하기 때문입니다. 여기에는 OS에서 시간 유지 및 시간 기반 활동을 구동하는 마더보드의 타이머 칩에서 발생하는 인터럽트가 포함됩니다. IRQL은 모든 "일반" 하드웨어 장치의 IRQL보다 높습니다.
IRQL 2 이상은 하드웨어 인터럽트에 의해 트리거되지 않지만 대기를 포함한 정상적인 스레드 스케줄링이 발생할 수 없는 커널 작업에 사용됩니다. 따라서 프로세서가 IRQL 2 이상이면 IRQL이 2 아래로 떨어질 때까지 해당 프로세서에서 스레드 컨텍스트 전환이 발생할 수 없습니다.
사용자 모드 코드는 항상 IRQL 0입니다. 커널 모드 코드는 0부터 최대값에 관계없이 모든 IRQL에서 실행될 수 있습니다. IRQL 1은 특별한 경우입니다. 이는 커널 모드일 뿐이지만 스케줄링에는 영향을 주지 않으며 실제로는 프로세서보다 스레드의 상태에 가깝습니다. 예를 들어 스레드 컨텍스트 전환 중에 저장되고 복원됩니다.
다양한 직렬화 보장을 유지하기 위해 대부분의 예외(0으로 나누기 또는 페이지 오류와 같은 메모리 액세스 위반)는 IRQL 2 이상에서 처리할 수 없습니다. (IRQL 2 btw는 일반적으로 "디스패치 수준" 또는 "DPC 수준"이라고 합니다.)
이제 드디어 이 버그체크 코드를 설명할 수 있게 되었습니다!
IRQL_NOT_LESS_OR_EQUAL의 가장 일반적인 경우는 페이지 오류("상주하지 않는" 가상 주소에 액세스하려는 시도) 또는 메모리 액세스 위반(읽기 전용 페이지에 쓰려는 시도 또는 정의되지 않은 페이지에 액세스하려는 시도)으로 인해 발생합니다. 전혀) IRQL 2 이상에서 발생합니다.
이러한 예외가 IRQL 0 또는 1에서 발생하면 시스템 제공 코드(예: 페이지 오류 처리기) 또는 개발자가 제공하는 예외 처리기에 의해 "처리"될 수 있습니다. 그러나 IRQL 2 이상에서 발생한 예외는 대부분 처리할 수 없습니다.
그러니까... 버그체크 코드는 "IRQL이 2 이상일 때 IRQL 0이나 1에서만 처리할 수 있는 유형의 예외가 발생했다"는 뜻입니다. 즉, "1보다 작거나 같지 않음"입니다. 이상한 표현이지만 거기에 있습니다.
이 버그 체크를 유발할 수 있는 몇 가지 다른 사항이 있으며 IRQL이 작거나 같지 않은 값이 항상 1은 아니지만 거의 발생하지 않습니다. WinDBG 문서에 이를 나열되어 있습니다.