Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bir sürücü yordamının yürütüleceği IRQL, hangi çekirdek modu sürücüsünün çağırabileceği destek yordamlarını belirler. Örneğin, bazı sürücü destek yordamları, çağıranın IRQL = DISPATCH_LEVEL'de çalışmasını gerektirir. Arayan PASSIVE_LEVEL daha yüksek bir IRQL'de çalışıyorsa diğerleri güvenli bir şekilde çağrılamaz.
Aşağıda, en yaygın olarak uygulanan standart sürücü yordamlarının çağrıldığı IRQL'lerin listesi yer alır. IRQL'ler en düşükten en yüksek önceliğe kadar listelenir.
PASSIVE_LEVEL
Kesmeler Maskelenmiş Kapalı - Yok.
Sürücü Yordamları PASSIVE_LEVEL'de Çalıştırılır - DriverEntry, AddDevice, Reinitialize, Unload yordamları, çoğu dağıtım yordamı, sürücü tarafından oluşturulan iş parçacıkları, çalışan iş parçacığı geri çağırmaları.
APC_DÜZEYİ
Kesmeler Maskeli Kapalı - APC_LEVEL kesmeler maskelenir.
Adlı Sürücü Yordamları APC_LEVEL - Bazı dağıtım yordamları (bkz . Dağıtım Yordamları ve IRQL'ler).
Dağıtım Seviyesi
Kesmeler Maskeli Kapalı - DISPATCH_LEVEL ve APC_LEVEL kesmeleri maskelenir. Cihaz, saat ve güç kesintileri oluşabilir.
Adlı Sürücü Yordamları DISPATCH_LEVEL - StartIo, AdapterControl, AdapterListControl, ControllerControl, IoTimer, Cancel (iptal döndürme kilidini tutarken), DpcForIsr, CustomTimerDpc, CustomDpc yordamları.
DIRQL
Kesmeler Maskeli Kapalı - Sürücünün kesme nesnesinin IRQL <= DIRQL'deki tüm kesmeleri. Güç ve saat hatası kesintilerinin yanı sıra, daha yüksek bir DIRQL değerine sahip cihaz kesintileri de oluşabilir.
DIRQL - InterruptService, SynchCritSection rutinlerinde çağrılan sürücü rutinleri.
APC_LEVEL ile PASSIVE_LEVEL arasındaki tek fark, APC_LEVEL'de yürütülen bir işlemin APC kesmelerini alamamasıdır. Ancak her iki IRQL de bir iş parçacığı bağlamı ve her ikisi de kodun sayfalanabileceğini gösterir.
En düşük düzey sürücüler, üç IRQL seviyesinden birinde çalışarak Giriş/Çıkış İstek Paketleri (IRP) işlemlerini gerçekleştirir:
PASSIVE_LEVEL, işlemcide kesintilerin maskelenmemesiyle, sürücünün Dağıtma rutinlerinde
DriverEntry, AddDevice, Reinitialize ve Unload yordamları da sürücü tarafından oluşturulan sistem iş parçacıkları gibi PASSIVE_LEVEL çalıştırılır.
DISPATCH_LEVEL ve APC_LEVEL kesmeleri işlemcide maskelenmişken, StartIo rutini içinde DISPATCH_LEVEL
AdapterControl, AdapterListControl, ControllerControl, IoTimer, Cancel (iptal döndürme kilidini barındırırken) ve CustomTimerDpc yordamları da DpcForIsr ve CustomDpc yordamları gibi DISPATCH_LEVEL'de çalıştırılır.
IsR ve SynchCritSection yordamlarında, sürücünün kesme nesnelerinin SyncIrql değerinden küçük veya buna eşit tüm kesmeler işlemcide maskelenmiş olarak, cihaz IRQL (DIRQL)
Yüksek seviye sürücülerin çoğu, herhangi iki IRQL'de çalışırken IRP'leri işler.
PASSIVE_LEVEL, işlemcide hiçbir kesinti devre dışı bırakılmadan sürücünün dağıtım yordamlarında
DriverEntry, Reinitialize, AddDevice ve Unload yordamları, sürücü tarafından oluşturulan sistem iş parçacıkları veya çalışan iş parçacığı geri çağırma yordamları veya dosya sistemi sürücüleri gibi PASSIVE_LEVEL de çalıştırılır.
DISPATCH_LEVEL, işlemcide DISPATCH_LEVEL ve APC_LEVEL kesmeleri maskelenmişken, sürücünün IoCompletion yordamlarında
IoTimer, Cancel ve CustomTimerDpc yordamları da DISPATCH_LEVEL'de çalıştırılır.
Bazı durumlarda, yığın depolama cihazlarının ara ve en düşük düzey sürücüleri IRQL APC_LEVEL'de çağrılır. Özellikle, bu durum bir dosya sistemi sürücüsünün düşük sürücülere IRP_MJ_READ isteği gönderdiği bir sayfa hatasında oluşabilir.
Çoğu standart sürücü yordamı, yalnızca uygun destek yordamlarını çağırmalarını sağlayan bir IRQL'de çalıştırılır. Örneğin, bir cihaz sürücüsünün IRQL DISPATCH_LEVEL çalışırken AllocateAdapterChannel çağrısı yapması gerekir. Çoğu cihaz sürücüsü bu yordamları StartIo yordamından çağırdığından, genellikle zaten DISPATCH_LEVEL'de çalışır.
Kendi IRP kuyruklarını ayarlayıp yöneten ve bu nedenle StartIo yordamı bulunmayan bir cihaz sürücüsü, AllocateAdapterChannel çağrısını yapması gerektiğinde mutlaka IRQL DISPATCH_LEVEL'de çalışıyor olmak zorunda değildir. Böyle bir sürücü , AllocateAdapterChannel çağrısını KeRaiseIrql ve KeLowerIrql çağrıları arasında iç içe yerleştirerek AllocateAdapterChannel çağırdığında gerekli IRQL'de çalışması ve çağrı yordamı denetimi yeniden kazandığında özgün IRQL'i geri yüklemesi gerekir.
Sürücü destek yordamlarını çağırırken aşağıdakilere dikkat edin.
Geçerli IRQL'den küçük bir Giriş NewIrql değeriyle KeRaiseIrql çağrılması önemli bir hataya neden olur. Özgün IRQL'i geri yüklemek dışında KeLowerIrql çağrısı (yani , KeRaiseIrql çağrısından sonra) önemli bir hataya neden olur.
IRQL >= DISPATCH_LEVEL çalışırken, çekirdek tanımlı dağıtıcı nesnelerinin sıfır olmayan bir aralığı beklemesi için KeWaitForSingleObject veya KeWaitForMultipleObjects çağrılması önemli bir hataya neden olur.
Olayların, semaforların, mutekslerin veya zamanlayıcıların sinyal durumuna ayarlanmasını güvenle bekleyebilen tek sürücü rutinleri, sürücü tarafından oluşturulmuş iş parçacıkları, DriverEntry ve Reinitialize rutinleri veya doğal olarak zaman uyumlu G/Ç işlemleri için gönderim rutinleri (çoğu cihaz G/Ç kontrol istekleri gibi) gibi keyfi olmayan bir iş parçacığı bağlamında IRQL PASSIVE_LEVEL seviyesinde çalışan rutinlerdir.
IRQL PASSIVE_LEVEL çalışırken bile disk belleğine alınabilen sürücü kodu, Wait parametresi TRUE olarak ayarlanmış KeSetEvent, KeReleaseSemaphore veya KeReleaseMutex çağrılamamalıdır. Böyle bir çağrı önemli bir sayfa hatasına neden olabilir.
IRQL APC_LEVEL'den daha yüksek bir seviyede çalışan herhangi bir rutin, sayfalı havuzdan bellek ayıramaz veya sayfalı havuzdaki belleğe güvenli bir şekilde erişemez. IRQL'in APC_LEVEL'den daha yüksek olduğu bir düzeyde çalışan bir rutin, bir sayfa hatasına neden oluyorsa, bu ölümcül bir hatadır.
Bir sürücü, KeAcquireSpinLockAtDpcLevel ve KeReleaseSpinLockFromDpcLevel'i çağırdığında IRQL DISPATCH_LEVEL çalışıyor olmalıdır.
Bir sürücü KeAcquireSpinLock çağırdığında IRQL <= DISPATCH_LEVEL seviyesinde çalışıyor olabilir, ancak bu döndürme kilidini KeReleaseSpinLock çağrısını yaparak serbest bırakması gerekir. Başka bir deyişle, KeReleaseSpinLockFromDpcLevel çağrısıyla KeAcquireSpinLock ile alınan bir döndürme kilidini serbest bırakmak bir programlama hatasıdır.
Bir sürücü IRQL > DISPATCH_LEVEL çalışırken KeAcquireSpinLockAtDpcLevel, KeReleaseSpinLockFromDpcLevel, KeAcquireSpinLock veya KeReleaseSpinLock çağrılamamalıdır.
ExInterlockedXxx rutini gibi bir spin lock kullanan destek rutininin çağrılması, eğer çağıranın IRQL'i zaten yükseltilmiş değilse, geçerli işlemcideki IRQL'i DISPATCH_LEVEL veya DIRQL'e yükseltir.
IRQL > PASSIVE_LEVEL çalışan sürücü kodu mümkün olan en kısa sürede yürütülmelidir. Bir rutinin çalıştırıldığı IRQL seviyesi ne kadar yüksekse, o rutinin mümkün olan en hızlı şekilde yürütülmesi, iyi bir genel performans için o kadar önemlidir. Örneğin, KeRaiseIrql'i çağıran herhangi bir sürücü, keLowerIrql'e en kısa sürede karşılıklı çağrı yapmalıdır.
Öncelikleri belirleme hakkında daha fazla bilgi için Zamanlama, İş Parçacığı Bağlamı ve IRQL teknik incelemesine bakın.