Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Některé ovladače režimu jádra, jako jsou sériové a paralelní ovladače, nemusí být rezidentní v paměti, pokud nejsou otevřená zařízení, která spravují. Pokud ale existuje aktivní připojení nebo port, musí být část kódu ovladače, která tento port spravuje, rezidentní, aby bylo možné zařízení obsluhovat. Pokud se port nebo připojení nepoužívá, kód ovladače se nevyžaduje. Naproti tomu ovladač disku, který obsahuje systémový kód, kód aplikace nebo systémový stránkovací soubor, musí být vždy rezidentem paměti, protože ovladač neustále přenáší data mezi jeho zařízením a systémem.
Ovladač pro sporadicky používané zařízení (například modem) může uvolnit systémové místo, když zařízení, které spravuje, není aktivní. Pokud umístíte do jedné části kód, který musí být rezidentem pro obsluhu aktivního zařízení, a pokud ovladač zamkne kód v paměti při použití zařízení, můžete tento oddíl určit jako stránkovatelný. Po otevření zařízení ovladače operační systém přenese stránkovatelný oddíl do paměti a ovladač ho uzamkne, dokud ho už nepotřebujete.
Tento postup používá kód zvukového ovladače CD systému. Kód ovladače je seskupený do stránkovatelných oddílů podle výrobce zařízení CD. Některé značky nemusí být v daném systému nikdy přítomny. I když CD-ROM v systému existuje, může se k němu přistupovat jen zřídka, takže seskupování kódu do stránkovatelných oddílů podle typu CD zajistí, aby se kód pro zařízení, která na konkrétním počítači neexistují, nikdy nenačetl. Při přístupu k zařízení ale systém načte kód pro příslušné zařízení CD. 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.
Pokud chcete izolovat stránkovatelný kód do pojmenovaného oddílu, označte ho následujícím direktivou kompilátoru:
#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. První čtyři písmena názvu oddílu (tj. PAGE) musí být velká písmena. The RoutineName identifies an entry point to be included in the pageable section.
Nejkratší platný název oddílu stránkovatelného kódu v souboru ovladače je jednoduše PAGE. Například direktiva pragma v následujícím příkladu kódu identifikuje RdrCreateConnection jako vstupní bod v oddílu kódu s možností stránky s názvem PAGE.
#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.
Ovladač může také zacházet s zřídka používanými daty jako se stránkovatelnými daty, aby bylo možné je také stránkovat, dokud zařízení, které podporuje, není aktivní. Například ovladač systémového mixéru používá stránkovatelná data. Zařízení mixéru nemá přidružené žádné asynchronní vstupně-výstupní operace, takže tento ovladač může učinit data stránkovatelnými.
Název stránkovatelného datového oddílu musí začínat čtyřmi písmeny PAGE a může za ním následovat až čtyři znaky, aby bylo možné oddíl jednoznačně identifikovat. První čtyři písmena názvu oddílu (tj. PAGE) musí být velká písmena.
Vyhněte se přiřazování stejných názvů k oddílům kódu a dat. Aby byl zdrojový kód čitelnější, vývojáři ovladačů obvykle přiřazují název PAGE oddílu s kódem stránky, protože tento název je krátký a může se objevit v mnoha alloc_text direktivách pragma. Delší názvy se pak přiřazují k jakýmkoli stránkovatelným datovým oddílům (například PAGEDATA pro data_seg, PAGEBSS pro bss_seg atd.), které ovladač může vyžadovat.
Například první dvě direktivy pragma v následujícím příkladu kódu definují dva stránkovatelné datové oddíly, PAGEDATA a PAGEBSS. PAGEDATA je deklarován pomocí direktivy pragma data_seg a obsahuje inicializovaná data. FUNKCE PAGEBSS je deklarována pomocí direktivy pragma bss_seg a obsahuje neinicializovaná data.
#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()
V tomto příkladu Variable1 a Array1 v kódu jsou explicitně inicializovány a jsou proto umístěny v části PAGEDATA.
Variable2 a Array2 jsou implicitně inicializovány nulou a jsou umístěny v části PAGEBSS.
Implicitně inicializace globálních proměnných na nulu zmenšuje velikost spustitelného souboru na disku a upřednostňuje se před explicitní inicializací na nulu. Explicitní nulové inicializaci by se mělo vyhnout kromě případů, kdy je potřebné umístit proměnnou do konkrétní datové části.
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.
Uzamčení oddílu je náročná operace, protože správce paměti musí před uzamčením stránek do paměti prohledávat seznam načtených modulů. 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. Dokud je čítač pro jakýkoli popisovač oddílu nenulový, tento oddíl zůstává uzamčený v paměti.
Popisovač oddílu je platný, pokud je načten jeho ovladač. Therefore, a driver should call MmLockPagableXxxSection only one time. If the driver requires more locking calls, it should use MmLockPagableSectionByHandle.
Pokud je oddíl stránkován při volání rutiny zámku, správce paměti načte oddíl do paměti a nastaví počet odkazů na jeden. 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.
Použití této techniky minimalizuje vliv ovladače na systémové prostředky. Když se ovladač spustí, může se uzamknout do paměti kódu a dat, která musí být rezidentní. Pokud pro své zařízení nejsou žádné nevyřízené vstupně-výstupní požadavky (to znamená, když je zařízení zavřené nebo pokud se zařízení nikdy neotevřelo), může ovladač odemknout stejný kód nebo data a umožnit jejich přesunutí na disk.
Jakmile se ovladač připojí k přerušení, jakýkoli kód ovladače, který lze volat během zpracování přerušení, musí být vždy rezidentní v paměti. Zatímco některé ovladače zařízení mohou být stránkovatelné nebo uzamčené do paměti na vyžádání, některá základní sada kódu ovladače a data musí být trvale rezidentní v systémovém prostoru.
Zvažte následující pokyny implementace pro uzamčení kódu nebo datového oddílu.
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. Dobrými příklady jsou ovladače, jako je sériový ovladač a paralelní ovladač: pokud zařízení, které nějaký ovladač spravuje, nemá otevřené popisovače, části kódu nejsou potřeba a mohou zůstat odloženy do stránkovací paměti. Přesměrovací ovladač a server jsou také dobrými příklady ovladačů, které tuto techniku mohou využít. Pokud neexistují žádná aktivní připojení, je možné obě tyto komponenty odkládat do swapu.
Celý stránkovatelný oddíl je zamknutý do paměti.
Jedna část kódu a jedna pro data pro každý ovladač je efektivní. Mnohé pojmenované oddíly, které lze stránkovat, jsou obecně neefektivní.
Udržujte čistě stránkovatelné oddíly oddělené od částí, které jsou stránkované, ale lze je uzamknout na vyžádání.
Tyto rutiny můžou způsobit těžkou vstupně-výstupní aktivitu, když správce paměti načte oddíl. 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.