Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Certos drivers de modo kernel, como os drivers serial e paralelos, não precisam ser residentes na memória, a menos que os dispositivos que gerenciam estejam abertos. No entanto, desde que haja uma conexão ou porta ativa, alguma parte do código do driver que gerencia essa porta deve ser residente para servir o dispositivo. Quando a porta ou conexão não está sendo usada, o código do driver não é necessário. Por outro lado, um driver para um disco que contém código do sistema, código do aplicativo ou o arquivo de paginação do sistema deve sempre ser residente na memória porque o driver transfere constantemente dados entre seu dispositivo e o sistema.
Um driver para um dispositivo usado esporadicamente (como um modem) pode liberar espaço no sistema quando o dispositivo que ele gerencia não está ativo. Se colocares numa única seção o código que deve ser residente para servir um dispositivo ativo, e se o teu driver bloquear o código na memória enquanto o dispositivo está a ser utilizado, pode-se designar essa seção como paginável. Quando o dispositivo do controlador é aberto, o sistema operativo traz a seção paginável para a memória e o controlador a bloqueia até que não seja mais necessário.
O código do driver de áudio do CD do sistema usa essa técnica. O código para o driver é agrupado em secções pagináveis de acordo com o fabricante da unidade de CD. Certas marcas podem nunca estar presentes num determinado sistema. Além disso, mesmo que exista um CD-ROM em um sistema, ele pode ser acessado com pouca frequência, portanto, agrupar o código em seções pagináveis por tipo de CD garante que o código para dispositivos que não existem em um computador específico nunca seja carregado. No entanto, quando o dispositivo é acessado, o sistema carrega o código para o dispositivo de CD apropriado. 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.
Para isolar o código paginável em uma seção nomeada, marque-o com a seguinte diretiva de compilador:
#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. As quatro primeiras letras do nome da seção (ou seja, "PÁGINA") devem ser maiúsculas. The RoutineName identifies an entry point to be included in the pageable section.
O nome válido mais curto para uma seção de código paginável em um arquivo de driver é simplesmente PAGE. Por exemplo, a diretiva pragma no exemplo de código a seguir identifica RdrCreateConnection como um ponto de entrada em uma seção de código paginável chamada 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.
Um driver também pode tratar dados raramente usados como pagináveis para que eles também possam ser paginados até que o dispositivo que ele suporta esteja ativo. Por exemplo, o driver do misturador do sistema usa dados pagináveis. O dispositivo misturador não tem E/S assíncrona associada a ele, de modo que esse driver pode tornar seus dados pagináveis.
O nome de uma seção de dados paginável deve começar com as quatro letras "PAGE" e pode ser seguido por até quatro caracteres para identificar exclusivamente a seção. As quatro primeiras letras do nome da seção (ou seja, "PÁGINA") devem ser maiúsculas.
Evite atribuir nomes idênticos a seções de código e dados. Para tornar o código-fonte mais legível, os desenvolvedores de drivers normalmente atribuem o nome PAGE à seção de código paginável porque esse nome é curto e pode aparecer em várias diretivas alloc_text pragma. Nomes mais longos são então atribuídos a quaisquer seções de dados pagináveis (por exemplo, PAGEDATA para data_seg, PAGEBSS para bss_seg e assim por diante) que o driver possa exigir.
Por exemplo, as duas primeiras diretivas pragma no exemplo de código a seguir definem duas seções de dados pagináveis, PAGEDATA e PAGEBSS. PAGEDATA é declarado usando a diretiva data_seg pragma e contém dados inicializados. PAGEBSS é declarado usando a diretiva bss_seg pragma e contém dados não inicializados.
#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()
Neste exemplo de código, Variable1 e Array1 são explicitamente inicializados e, portanto, são colocados na seção PAGEDATA.
Variable2 e Array2 são implicitamente inicializadas com zero e são colocadas na seção PAGEBSS.
A inicialização implícita de variáveis globais para zero reduz o tamanho do arquivo executável no disco e é preferível à inicialização explícita a zero. A inicialização zero explícita deve ser evitada, exceto nos casos em que é necessária para colocar uma variável em uma seção de dados específica.
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.
Bloquear uma seção é uma operação cara porque o gerenciador de memória deve pesquisar sua lista de módulos carregados antes de bloquear as páginas na memória. 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. Embora o contador de qualquer identificador de seção seja diferente de zero, essa seção permanece bloqueada na memória.
O identificador para uma secção é válido desde que o respetivo driver esteja carregado. Therefore, a driver should call MmLockPagableXxxSection only one time. If the driver requires more locking calls, it should use MmLockPagableSectionByHandle.
Se a seção for paginada quando a rotina de bloqueio for chamada, o gerenciador de memória páginas na seção e definirá sua contagem de referência como uma. 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.
O uso dessa técnica minimiza o efeito do driver nos recursos do sistema. Quando o driver é executado, pode fixar na memória o código e os dados que precisam permanecer residentes. Quando não há solicitações de E/S pendentes para o seu dispositivo, (ou seja, quando o dispositivo é fechado ou se o dispositivo nunca foi aberto), o driver pode desbloquear o mesmo código ou dados, tornando-o disponível para ser paginado.
No entanto, depois de um driver conectar a interrupções, qualquer código de driver que possa ser chamado durante o processamento de interrupção sempre deve ser residente em memória. Embora alguns drivers de dispositivo possam ser pagináveis ou fixados na memória sob demanda, um conjunto central de código e dados desse driver deve permanecer permanentemente residente no espaço do sistema.
Considere as seguintes diretrizes de implementação para bloquear um código ou seção de dados.
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. Drivers como o driver serial e o driver paralelo são bons exemplos: se não houver alças abertas para um dispositivo gerenciado por esse driver, partes do código não são necessárias e podem permanecer paginadas. O redirecionador e o servidor também são bons exemplos de drivers que podem usar essa técnica. Quando não há conexões ativas, ambos os componentes podem ser transferidos para a memória virtual.
Toda a seção paginável está bloqueada na memória.
Uma seção para código e outra para dados por driver é eficiente. Muitas seções nomeadas e pagináveis são geralmente ineficientes.
Mantenha separadas as seções puramente pagináveis e as seções paginadas, mas bloqueadas sob demanda.
Essas rotinas podem causar atividade de E/S pesada quando o gerenciador de memória carrega a seção. 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.