Fonction MmAllocateMdlForIoSpace (wdm.h)
La routine MmAllocateMdlForIoSpace alloue un MDL et initialise cette MDL pour décrire un ensemble de plages d’adresses physiques dans l’espace d’adressage d’E/S.
Syntaxe
NTSTATUS MmAllocateMdlForIoSpace(
[in] PMM_PHYSICAL_ADDRESS_LIST PhysicalAddressList,
[in] SIZE_T NumberOfEntries,
[out] PMDL *NewMdl
);
Paramètres
[in] PhysicalAddressList
Pointeur vers un tableau de structures MM_PHYSICAL_ADDRESS_LIST qui décrivent les plages d’adresses physiques à inclure dans le MDL alloué.
[in] NumberOfEntries
Nombre d’éléments dans le tableau MM_PHYSICAL_ADDRESS_LIST pointé vers par PhysicalAddressList.
[out] NewMdl
Pointeur vers un emplacement vers lequel la routine écrit un pointeur vers le MDL nouvellement alloué.
Valeur retournée
MmAllocateMdlForIoSpace retourne STATUS_SUCCESS si elle réussit. Les valeurs de retour d’erreur possibles incluent les codes status suivants.
Code de retour | Description |
---|---|
STATUS_INVALID_PARAMETER_1 | Une adresse physique n’est pas alignée sur une limite de page ; ou une plage d’adresses physique n’est pas un multiple de la taille de la page ; ou une plage d’adresses physique est utilisée par le système d’exploitation pour la RAM et n’est pas disponible en tant qu’espace d’E/S. |
STATUS_INSUFFICIENT_RESOURCES | Les ressources système sont insuffisantes pour effectuer l’opération demandée. |
Ne partez pas du principe que la liste précédente de codes de retour d’erreur est exhaustive. La routine peut retourner des codes d’erreur qui n’apparaissent pas dans la liste.
Remarques
Cette routine accepte, en tant que paramètre d’entrée, un tableau de structures MM_PHYSICAL_ADDRESS_LIST qui décrivent un ensemble de plages d’adresses physiques dans l’espace d’adressage d’E/S et alloue une MDL qui décrit ces plages. Les plages d’adresses physiques consécutives dans le tableau ne doivent pas nécessairement être contiguës.
Les plages d’adresses physiques dans le tableau PhysicalAddressList doivent remplir les conditions suivantes :
L’adresse physique de base de chaque plage doit être alignée sur une limite PAGE_SIZE en mémoire.
La taille, en octets, de chaque plage doit être un multiple entier de PAGE_SIZE.
Toutes les plages d’adresses physiques doivent être en mémoire disponible en tant qu’espace d’adressage d’E/S. Ils ne peuvent pas se trouver dans l’espace mémoire utilisé par le système d’exploitation pour la RAM.
La taille totale de toutes les plages doit être inférieure à 4 gigaoctets. Plus précisément, la taille totale ne doit pas dépasser 2^32 - 1 octets.
L’appelant est responsable de libérer la MDL allouée lorsqu’elle n’est plus nécessaire. Pour libérer le MDL, appelez la routine IoFreeMdl . Pour plus d’informations sur les dll MDL, consultez Utilisation de MDL.
Le MDL créé par MmAllocateMdlForIoSpace n’est pas mappé à la mémoire virtuelle, mais peut être fourni à une routine telle que MapTransferEx pour lancer un transfert DMA vers ou à partir des plages de mémoire physique décrites par le MDL. Pour mapper cette MDL à une plage contiguë d’adresses virtuelles afin qu’elle soit accessible par le processeur, appelez la routine MmMapLockedPagesSpecifyCache .
Seules les plages de l’espace d’adressage physique qui ne sont pas réservées par le système d’exploitation pour une utilisation en tant que mémoire sont disponibles pour les pilotes en tant qu’espace d’adressage d’E/S. Les pilotes utilisent l’espace d’adressage d’E/S pour accéder aux ressources matérielles mappées en mémoire, telles que les registres d’appareils. Lorsqu’un pilote démarre, il peut recevoir une ou plusieurs plages d’adresses physiques en tant que ressources matérielles traduites. Pour plus d’informations, consultez Mappage d’adresses Bus-Relative à des adresses virtuelles.
Dans certaines architectures de processeur, telles que le x86, les appareils peuvent être mappés à la mémoire ou mappés aux adresses de port dans un espace d’adressage d’E/S spécial dédié aux appareils et séparé de l’espace d’adressage mémoire. Les pilotes peuvent utiliser MmAllocateMdlForIoSpace pour allouer des listes mdl uniquement pour les appareils mappés en mémoire.
Exemples
L’exemple de code suivant montre comment construire un tableau de structures MM_PHYSICAL_ADDRESS_LIST qui décrivent les plages d’adresses physiques à inclure dans le MDL alloué.
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);
Dans cet exemple, l’adresse physique de départ est spécifiée par la BasePhysicalAddress
variable . Le nombre d’octets dans chaque plage d’adresses physiques est spécifié par la ChunkSize
variable. Le décalage d’octet entre le début d’une plage physique et le début de la suivante est spécifié par la Stride
variable. BasePhysicalAddress
doit être aligné sur une limite de page en mémoire et ChunkSize
doit Stride
être plusieurs de la taille de la page.
Configuration requise
Condition requise | Valeur |
---|---|
Client minimal pris en charge | Disponible à partir de Windows 8. |
Plateforme cible | Universal |
En-tête | wdm.h (inclure Wdm.h) |
Bibliothèque | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL |