Função MmAllocateMdlForIoSpace (wdm.h)

A rotina MmAllocateMdlForIoSpace aloca um MDL e inicializa esse MDL para descrever um conjunto de intervalos de endereços físicos no espaço de endereço de E/S.

Sintaxe

NTSTATUS MmAllocateMdlForIoSpace(
  [in]  PMM_PHYSICAL_ADDRESS_LIST PhysicalAddressList,
  [in]  SIZE_T                    NumberOfEntries,
  [out] PMDL                      *NewMdl
);

Parâmetros

[in] PhysicalAddressList

Um ponteiro para uma matriz de estruturas MM_PHYSICAL_ADDRESS_LIST que descrevem os intervalos de endereços físicos a serem incluídos no MDL alocado.

[in] NumberOfEntries

O número de elementos na matriz MM_PHYSICAL_ADDRESS_LIST apontada por PhysicalAddressList.

[out] NewMdl

Um ponteiro para um local no qual a rotina grava um ponteiro para o MDL recém-alocado.

Retornar valor

MmAllocateMdlForIoSpace retornará STATUS_SUCCESS se for bem-sucedido. Os possíveis valores retornados por erro incluem os seguintes códigos de status.

Código de retorno Descrição
STATUS_INVALID_PARAMETER_1 Um endereço físico não está alinhado a um limite de página; ou um intervalo de endereços físicos não é um múltiplo do tamanho da página; ou um intervalo de endereços físicos é usado pelo sistema operacional para RAM e não está disponível para uso como espaço de E/S.
STATUS_INSUFFICIENT_RESOURCES Recursos insuficientes do sistema estão disponíveis para executar a operação solicitada.

Não suponha que a lista anterior de códigos de retorno de erro seja exaustiva. A rotina pode retornar códigos de erro que não aparecem na lista.

Comentários

Essa rotina aceita, como parâmetro de entrada, uma matriz de estruturas MM_PHYSICAL_ADDRESS_LIST que descrevem um conjunto de intervalos de endereços físicos no espaço de endereço de E/S e aloca um MDL que descreve esses intervalos. Intervalos de endereços físicos consecutivos na matriz não precisam ser contíguos.

Os intervalos de endereços físicos na matriz PhysicalAddressList devem atender às seguintes condições:

  • O endereço físico base para cada intervalo deve ser alinhado a um limite de PAGE_SIZE na memória.

  • O tamanho, em bytes, de cada intervalo deve ser um múltiplo inteiro de PAGE_SIZE.

  • Todos os intervalos de endereços físicos devem estar na memória disponível para uso como espaço de endereço de E/S. Eles não podem estar no espaço de memória usado pelo sistema operacional para RAM.

  • O tamanho total de todos os intervalos deve ser menor que 4 gigabytes. Especificamente, o tamanho total não deve exceder 2^32 - 1 bytes.

O chamador é responsável por liberar o MDL alocado quando ele não é mais necessário. Para liberar o MDL, chame a rotina IoFreeMdl . Para obter mais informações sobre MDLs, consulte Usando MDLs.

O MDL criado por MmAllocateMdlForIoSpace não é mapeado para memória virtual, mas pode ser fornecido a uma rotina como MapTransferEx para iniciar uma transferência de DMA de ou para os intervalos de memória física descritos pelo MDL. Para mapear esse MDL para um intervalo contíguo de endereços virtuais para que ele possa ser acessado pelo processador, chame a rotina MmMapLockedPagesSpecifyCache .

Somente intervalos do espaço de endereço físico que não são reservados pelo sistema operacional para uso como memória estão disponíveis para drivers para uso como espaço de endereço de E/S. Os drivers usam espaço de endereço de E/S para acessar recursos de hardware mapeados em memória, como registros de dispositivo. Quando um driver é iniciado, ele pode receber um ou mais intervalos de endereços físicos como recursos de hardware traduzidos. Para obter mais informações, consulte Mapeando endereços Bus-Relative para endereços virtuais.

Em algumas arquiteturas de processador, como o x86, os dispositivos podem ser mapeados em memória ou mapeados para endereços de porta em um espaço de endereço de E/S especial dedicado aos dispositivos e separados do espaço de endereço de memória. Os drivers podem usar MmAllocateMdlForIoSpace para alocar MDLs somente para dispositivos mapeados em memória.

Exemplos

O exemplo de código a seguir mostra como construir uma matriz de estruturas MM_PHYSICAL_ADDRESS_LIST que descrevem os intervalos de endereços físicos a serem incluídos no MDL alocado.

extern ULONG64 BasePhysicalAddress;
extern SIZE_T ChunkSize;
extern SIZE_T Stride;

#define ARRAYSIZE(x)  (sizeof(x)/sizeof((x)[0]))
 
NTSTATUS Status;
PMDL Mdl;
MM_PHYSICAL_ADDRESS_LIST AddressList[3];
 
AddressList[0].PhysicalAddress.QuadPart = BasePhysicalAddress;
AddressList[0].NumberOfBytes = ChunkSize;
 
BasePhysicalAddress += Stride;
 
AddressList[1].PhysicalAddress.QuadPart = BasePhysicalAddress;
AddressList[1].NumberOfBytes = ChunkSize;
 
BasePhysicalAddress += Stride;
 
AddressList[2].PhysicalAddress.QuadPart = BasePhysicalAddress;
AddressList[2].NumberOfBytes = ChunkSize;
 
Status = MmAllocateMdlForIoSpace (AddressList, ARRAYSIZE(AddressList), &Mdl);

Neste exemplo, o endereço físico inicial é especificado pela BasePhysicalAddress variável . O número de bytes em cada intervalo de endereços físicos é especificado pela ChunkSize variável . O deslocamento de bytes do início de um intervalo físico até o início do próximo é especificado pela Stride variável . BasePhysicalAddress deve ser alinhado a um limite de página na memória e ChunkSize e Stride deve ser múltiplos do tamanho da página.

Requisitos

Requisito Valor
Cliente mínimo com suporte Disponível a partir do Windows 8.
Plataforma de Destino Universal
Cabeçalho wdm.h (include Wdm.h)
Biblioteca NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL

Confira também

IoFreeMdl

MDL

MM_PHYSICAL_ADDRESS_LIST

MapTransferEx

MmMapLockedPagesSpecifyCache