Função MmAllocateMdlForIoSpace (wdm.h)
A rotina MmAllocateMdlForIoSpace aloca um de 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 de 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 apontado por PhysicalAddressList.
[out] NewMdl
Um ponteiro para um local no qual a rotina grava um ponteiro no MDL recém-alocado.
Valor de retorno
MmAllocateMdlForIoSpace retornará STATUS_SUCCESS se for bem-sucedido. Os valores de retorno de erro possíveis 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ço físico 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.
Observações
Essa rotina aceita, como um 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. Os intervalos de endereços físicos consecutivos na matriz não são necessários para serem 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 a 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 de 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 para uma rotina como MapTransferEx para iniciar uma transferência de DMA para ou dos 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 de 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 pela 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 endereços de Bus-Relative de mapeamento 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 de 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 variável BasePhysicalAddress
. O número de bytes em cada intervalo de endereços físicos é especificado pela variável ChunkSize
. O deslocamento de bytes do início de um intervalo físico até o início do próximo é especificado pela variável Stride
.
BasePhysicalAddress
deve ser alinhado a um limite de página na memória, e ChunkSize
e Stride
devem ser múltiplos do tamanho da página.
Requisitos
Requisito | Valor |
---|---|
de cliente com suporte mínimo | Disponível a partir do Windows 8. |
da Plataforma de Destino | Universal |
cabeçalho | wdm.h (inclua Wdm.h) |
biblioteca | NtosKrnl.lib |
de DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL |