Aracılığıyla paylaş


Sayfalanabilir kodu veya verileri kilitleme

Seri ve paralel sürücüler gibi bazı çekirdek modu sürücülerinin, yönetdikleri cihazlar açık olmadığı sürece bellekte yerleşik olması gerekmez. Ancak etkin bir bağlantı veya bağlantı noktası olduğu sürece, bu bağlantı noktasını yöneten sürücü kodunun bir bölümü cihaza hizmet vermek için yerleşik olmalıdır. Bağlantı noktası veya bağlantı kullanılmadığında sürücü kodu gerekli değildir. Buna karşılık, sistem kodu, uygulama kodu veya sistem disk belleği dosyası içeren bir disk sürücüsü her zaman bellekte yerleşik olmalıdır çünkü sürücü sürekli olarak cihazıyla sistem arasında veri aktarır.

Düzensiz olarak kullanılan bir cihazın sürücüsü (modem gibi), yönettiği cihaz etkin olmadığında sistem alanı boşaltabilir. Etkin bir cihaza hizmet vermek için yerleşik olması gereken kodu tek bir bölüme yerleştirirseniz ve sürücünüz cihaz kullanılırken kodu belleğe kilitlerse, bu bölümü sayfalanabilir olarak belirleyebilirsiniz. Sürücü cihazı açıldığında, işletim sistemi sayfalanabilir bölümü belleğe getirir ve sürücü bu bölümü artık gerekmediğinde orada kilitler.

Sistem CD ses sürücüsü kodu bu tekniği kullanır. Sürücü kodu, CD cihazının üreticisine göre sayfalanabilir bölümler halinde gruplandırılır. Belirli markalar belirli bir sistemde asla mevcut olmayabilir. Ayrıca, sistemde bir CD-ROM olsa bile, buna seyrek olarak erişilebilir, bu nedenle kodu CD türüne göre sayfalanabilir bölümler halinde gruplandırma, belirli bir bilgisayarda var olmayan cihazlar için kodun hiçbir zaman yüklenmemesini sağlar. Ancak, cihaza erişildiğinde sistem uygun CD cihazının kodunu yükler. Then the driver calls the MmLockPagableCodeSection routine, as described later in this article, to lock its code into memory while its device is being used.

Sayfalama yapılabilir kodu adlandırılmış bir bölüme izole etmek için aşağıdaki derleyici yönergesiyle işaretleyin:

#pragma alloc_text(PAGE*Xxx***, *RoutineName***)

The name of a pageable code section must start with the four letters "PAGE" and can be followed by up to four characters (represented here as Xxx) to uniquely identify the section. Bölüm adının ilk dört harfi ("SAYFA") büyük harfle yazılmalıdır. The RoutineName identifies an entry point to be included in the pageable section.

Sürücü dosyasındaki sayfalanabilir kod bölümü için en kısa geçerli ad yalnızca PAGE'dir. Örneğin, aşağıdaki kod örneğindeki pragma yönergesi, RdrCreateConnection PAGE adlı sayfalanabilir bir kod bölümünde giriş noktası olarak tanımlar.

#ifdef  ALLOC_PRAGMA 
#pragma alloc_text(PAGE, RdrCreateConnection) 
#endif 

MmLockPagableCodeSection locks in the whole contents of the section that contains the routine referenced in the call. In other words, this call makes every routine associated with the same PAGEXxx identifier resident and locked in memory. In other words, this call makes every routine associated with the same PAGEXxx identifier resident and locked in memory.

MmLockPagableCodeSection returns a handle to be used when unlocking the section (by calling the MmUnlockPagableImageSection routine) or when the driver must lock the section from additional locations in its code.

Sürücü, nadiren kullanılan verileri de sayfalanabilir olarak değerlendirebilir, böylece desteklediği cihaz etkin olana kadar bu veriler disk dışına taşınabilir. Örneğin, sistem karıştırıcı sürücüsü sayfalanabilir verileri kullanır. Karıştırıcı cihazın kendisiyle ilişkilendirilmiş zaman uyumsuz Giriş/Çıkış yoktur, bu nedenle sürücü verilerini sayfalanabilir yapabilir.

Sayfalanabilir veri bölümünün adı dört harfli "PAGE" ile başlamalıdır ve bölümü benzersiz olarak tanımlamak için dört karaktere kadar takip edilebilir. Bölüm adının ilk dört harfi ("SAYFA") büyük harfle yazılmalıdır.

Kod ve veri bölümlerine aynı adları atamaktan kaçının. Kaynak kodu daha okunabilir hale getirmek için sürücü geliştiricileri genellikle pageable code bölümüne PAGE adını atar çünkü bu ad kısadır ve çok sayıda alloc_text pragma yönergesinde görünebilir. Daha sonra daha uzun adlar, sürücünün gerektirebileceği sayfalanabilir veri bölümlerine (örneğin, data_seg için PAGEDATA, bss_seg için PAGEBSS vb.) atanır.

Örneğin, aşağıdaki kod örneğindeki ilk iki pragma yönergesi pagedata ve PAGEBSS olarak iki sayfalanabilir veri bölümü tanımlar. PAGEDATA, data_seg pragma yönergesi kullanılarak bildirilir ve başlatılan verileri içerir. PAGEBSS, bss_seg pragma yönergesi kullanılarak bildirilir ve başlatılmamış veriler içerir.

#pragma data_seg("PAGEDATA")
#pragma bss_seg("PAGEBSS")

INT Variable1 = 1;
INT Variable2;

CHAR Array1[64*1024] = { 0 };
CHAR Array2[64*1024];

#pragma data_seg()
#pragma bss_seg()

Bu kod örneğinde, Variable1 ve Array1 açıkça başlatılır ve bu nedenle PAGEDATA bölümüne yerleştirilir. Variable2 ve Array2 örtük olarak sıfırdan başlatılır ve PAGEBSS bölümüne yerleştirilir.

Genel değişkenlerin örtük olarak sıfır olarak başlatılması, disk üzerindeki yürütülebilir dosyanın boyutunu küçültür ve açık başlatma yerine sıfır olarak tercih edilir. Gerekli durumlar haricinde, belirli bir veri bölümüne değişken yerleştirmek için açık sıfırdan başlatma yapılmamalıdır.

To make a data section memory-resident and lock it in memory, a driver calls MmLockPagableDataSection, passing a data item that appears in the pageable data section. MmLockPagableDataSection returns a handle to be used in subsequent locking or unlocking requests.

To restore a locked section's pageable status, call MmUnlockPagableImageSection, passing the handle value returned by MmLockPagableCodeSection or MmLockPagableDataSection, as appropriate. A driver's Unload routine must call MmUnlockPagableImageSection to release each handle it obtains for lockable code and data sections.

Sayfaları belleğe kilitlemeden önce bellek yöneticisinin yüklenen modül listesinde arama yapması gerektiğinden bölümü kilitlemek pahalı bir işlemdir. If a driver locks a section from many locations in its code, it should use the more efficient MmLockPagableSectionByHandle after its initial call to MmLockPagableXxxSection.

The handle passed to MmLockPagableSectionByHandle is the handle returned by the earlier call to MmLockPagableCodeSection or MmLockPagableDataSection.

The memory manager maintains a count for each section handle and increments this count every time that a driver calls MmLockPagableXxx for that section. A call to MmUnlockPagableImageSection decrements the count. Herhangi bir bölüm tutacağının sayacı sıfırdan farklı olduğu sürece, o bölüm bellekte kilitli kalmaya devam eder.

Bir bölümün tanıtıcısı, sürücüsü yüklü olduğu sürece geçerlidir. Therefore, a driver should call MmLockPagableXxxSection only one time. If the driver requires more locking calls, it should use MmLockPagableSectionByHandle.

Bellek yöneticisi kilit yordamı çağrıldığında bölüm sayfalanmışsa, bölümü belleğe alır ve başvuru sayısını bire ayarlar. If the section is paged out when the lock routine is called, the memory manager pages in the section and sets its reference count to one.

Bu tekniğin kullanılması, sürücünün sistem kaynakları üzerindeki etkisini en aza indirir. Sürücü çalıştığında, yerleşik olması gereken kodu ve verileri belleğe kilitleyebilir. Cihazı için bekleyen I/O talepleri olmadığında (yani, cihaz kapatıldığında veya cihaz hiç açılmadığında), sürücü aynı kodu veya veriyi serbest bırakabilir ve bunların sayfalama için müsait olmasını sağlayabilir.

Ancak, bir sürücü kesmeleri bağladıktan sonra, kesme işlemi sırasında çağrılabilen tüm sürücü kodları her zaman bellekte yerleşik olmalıdır. Bazı cihaz sürücüleri isteğe bağlı olarak sayfa belleğine alınabiliyor veya belleğe kilitlenebiliyor olsa da, bu tür bir sürücü kodunun ve verilerinin bazı çekirdek kod kümesinin sistem alanında sürekli olarak yer alması gerekir.

Bir kodu veya veri bölümünü kilitlemek için aşağıdaki uygulama yönergelerini göz önünde bulundurun.

  • The primary use of the Mm(Un)LockXxx routines is to enable normally nonpaged code or data to be made pageable and brought in as nonpaged code or data. Seri sürücü ve paralel sürücü gibi sürücüler iyi örneklerdir: Bu tür bir sürücünün yönettiği bir cihazda açık kulp yoksa, kod bölümleri gerekli değildir ve sayfalanmış halde tutulabilir. Yönlendirici ve sunucu da bu tekniği kullanabilen sürücüler arasında iyi örneklerdir. Etkin bağlantı olmadığında, bu bileşenlerin her ikisi de bellekten çıkartılabilir.

  • Sayfalanabilir bölümün tamamı belleğe kilitlenir.

  • Kod için bir bölüm ve sürücü başına veri için bir bölüm verimlidir. Adlandırılmış, sayfalanabilir bölümlerin çoğu genellikle verimsizdir.

  • Tamamen sayfalanabilir bölümleri ve sayfalanmış ancak isteğe bağlı olarak kilitlenmiş bölümleri ayrı tutun.

  • Bellek yöneticisi bölümü yüklediğinde bu rutinler yoğun G/Ç etkinliğine neden olabilir. If a driver must lock a section from several locations in its code, it should use MmLockPagableSectionByHandle. If a driver must lock a section from several locations in its code, it should use MmLockPagableSectionByHandle.