Nó phức tạp lắm. ;)
Không, thực sự, nó là.
IRQL là viết tắt của "Cấp yêu cầu ngắt". Đó là một số, từ 0 đến 31 trên các hệ thống Windows x86 và 0 đến 15 trên các hệ thống x64. Nó đại diện cho "tầm quan trọng" của một tác vụ chế độ kernel so với các tác vụ chế độ kernel khác.
IRQL là trạng thái do bộ xử lý xác định của Windows - không phải của quy trình hoặc luồng - cho biết Windows có hay không bất cứ điều gì bộ xử lý đang làm có thể bị gián đoạn bởi các tác vụ khác. Nếu một tác vụ mới (như thói quen dịch vụ ngắt) có IRQL cao hơn IRQL hiện tại của bộ xử lý, thì có, nó có thể làm gián đoạn tác vụ hiện tại; nếu không thì không. Trên hệ thống đa bộ xử lý, mỗi bộ xử lý có IRQL riêng. Điều này bao gồm "Bộ xử lý logic" được tạo bởi siêu phân luồng.
(Tôi sử dụng từ "mức độ quan trọng" thay vì "mức độ ưu tiên" vì "mức độ ưu tiên" trong Windows đề cập đến mức độ ưu tiên của luồng và IRQL là một cái gì đó khác nhau. Không giống như mức độ ưu tiên của luồng, các tác vụ kernel trong cùng một IRQL không bị cắt thời gian và IRQL không phát sinh ' t có thể tự động tăng và giảm.)
(Tôi cũng nên đề cập rằng thuật ngữ "tác vụ hạt nhân" ở đây không phải là chính thức. Windows không thực sự gọi những thứ này là "tác vụ hạt nhân", chúng không phải là đối tượng được quản lý như ví dụ như các tiến trình và luồng và không có liên quan đến nhiệm vụ x86 " cổng "cũng như bất kỳ thứ gì được hiển thị trong" Trình quản lý tác vụ ". Vì tôi (và những người khác) sử dụng thuật ngữ ở đây," tác vụ chế độ lõi "thực sự bao trùm" mọi thứ với một bắt đầu và kết thúc được xác định cần được thực hiện trong chế độ kernel tại IRQL 2 hoặc ở trên. "Một thói quen dịch vụ ngắt là một ví dụ về" tác vụ chế độ lõi "; đó là một thói quen DPC. Nhưng một ví dụ khác có thể là mã trong một luồng chế độ kernel. Các luồng như vậy bắt đầu ở IRQL 0, nhưng nếu là một phần của mã tăngđến IRQL 2 trở lên, thực hiện điều gì đó và sau đó quay lại IRQL trước đó, phần IRQL cao của mã là một ví dụ về cái mà tôi gọi là "tác vụ hạt nhân" ở đây. )
Giám sát hiệu suất hiển thị thời gian ở IRQL 2 là "% DPC time" và thời gian ở IRQL> 2 là "% thời gian gián đoạn", bất kể thời gian thực sự được sử dụng trong thói quen DPC hay ISR hay là kết quả của việc tăng IRQL từ một giá trị thấp hơn. Mỗi cái là một tập hợp con của PerfMon hiển thị là "% thời gian đặc quyền" - nên được gắn nhãn là "thời gian chế độ kernel".
Khi một tác vụ kernel được bắt đầu ở IRQL 2 trở lên, nó sẽ chạy đến hoàn thành trước khi mọi thứ khác ở cùng IRQL sẽ được khởi động trên cùng một bộ xử lý. Nó có thể bị gián đoạn bởi một nhiệm vụ IRQL cao hơn (lần lượt bị gián đoạn bởi một nhiệm vụ IRQL cao hơn, v.v.), nhưng khi các nhiệm vụ IRQL cao hơn hoàn thành, điều khiển sẽ quay trở lại nhiệm vụ mà nó bị gián đoạn.
IRQL chủ yếu là một cơ chế tuần tự hóa . (Nhiều người nói "đồng bộ hóa", nhưng tôi thích từ này vì nó mô tả chính xác hơn kết quả.) Mục đích của nó là giúp đảm bảo rằng nhiều tác vụ trên cùng một CPU truy cập vào một số tài nguyên được chia sẻ - chủ yếu là các cấu trúc dữ liệu được chia sẻ trong không gian nhân hệ điều hành - không được phép làm gián đoạn lẫn nhau theo những cách có thể làm hỏng các cấu trúc đó.
Ví dụ, rất nhiều dữ liệu trong nhân Windows, đặc biệt là dữ liệu quản lý bộ nhớ và dữ liệu được sử dụng bởi bộ lập lịch luồng, được "tuần tự hóa" tại IRQL 2. Điều đó có nghĩa là mọi tác vụ muốn sửa đổi dữ liệu đó phải được chạy tại IRQL 2 khi nó làm như vậy. Nếu tác vụ IRQL cao hơn cố ghi dữ liệu đó, điều đó có thể gây ra tham nhũng, vì nó có thể đã làm gián đoạn tác vụ IRQL 2 có thể ở giữa chu trình đọc-sửa-ghi trên cùng dữ liệu đó. Vì vậy, các nhiệm vụ IRQL cao hơn đơn giản là không được phép làm điều đó.
Các tác vụ IRQL cao hơn chủ yếu là các thói quen dịch vụ ngắt của trình điều khiển thiết bị, bởi vì tất cả các ngắt của thiết bị xảy ra ở IRQL> 2. Điều này bao gồm ngắt từ chip hẹn giờ trên bo mạch chủ điều khiển thời gian và hoạt động theo thời gian trong HĐH. IRQL của nó cao hơn tất cả các thiết bị phần cứng "thông thường".
IRQL 2 trở lên được sử dụng cho các tác vụ kernel không được kích hoạt bởi các ngắt phần cứng nhưng trong thời gian đó lập lịch luồng thông thường - bao gồm cả chờ đợi - không thể xảy ra. Do đó, một khi bộ xử lý ở IRQL 2 trở lên, không có chuyển đổi ngữ cảnh luồng nào có thể xảy ra trên bộ xử lý đó cho đến khi IRQL giảm xuống dưới 2.
Mã chế độ người dùng luôn ở IRQL 0. Mã chế độ hạt nhân có thể chạy ở bất kỳ IRQL nào từ 0 đến bất kỳ giá trị tối đa nào. IRQL 1 là trường hợp đặc biệt; nó chỉ là chế độ kernel nhưng không có tác động lên lịch trình, và thực sự là trạng thái của một luồng hơn so với bộ xử lý - ví dụ, nó được lưu và khôi phục trong các chuyển đổi ngữ cảnh của luồng.
Để duy trì các đảm bảo tuần tự hóa khác nhau, hầu hết các trường hợp ngoại lệ (những thứ như chia cho 0 hoặc vi phạm truy cập bộ nhớ như lỗi trang) chỉ đơn giản là không thể xử lý tại IRQL 2 trở lên. (IRQL 2 btw thường được gọi là "cấp công văn" hoặc "cấp DPC".)
Và bây giờ chúng ta cuối cùng có thể giải thích mã lỗi này!
Trường hợp phổ biến nhất của IRQL_NOT_LESS_OR_EQUAL là do lỗi trang (cố gắng truy cập địa chỉ ảo "không thường trú") hoặc vi phạm quyền truy cập bộ nhớ (cố ghi vào trang chỉ đọc hoặc truy cập trang không được xác định ở tất cả), điều đó xảy ra ở IRQL 2 trở lên.
Nếu các ngoại lệ như vậy được nêu ra tại IRQL 0 hoặc 1, chúng có thể được "xử lý" bằng mã do hệ thống cung cấp (như trình xử lý lỗi trang) hoặc bởi một trình xử lý ngoại lệ do nhà phát triển cung cấp. Tuy nhiên, hầu hết các trường hợp ngoại lệ không thể được xử lý nếu chúng xảy ra ở IRQL 2 trở lên.
Vì vậy, ... mã kiểm tra lỗi có nghĩa là "ngoại lệ của một loại chỉ có thể được xử lý tại IRQL 0 hoặc 1 xảy ra khi IRQL ở mức 2 hoặc cao hơn." tức là "không nhỏ hơn hoặc bằng 1". Từ ngữ lạ, nhưng nó có.
Có một vài điều khác có thể kích hoạt kiểm tra lỗi này và giá trị mà IRQL không ít hơn hoặc bằng không phải luôn luôn là 1, nhưng chúng hiếm khi xảy ra. Tài liệu WinDBG liệt kê chúng.