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 |