Función MmAllocateContiguousMemorySpecifyCacheNode (wdm.h)
La rutina MmAllocateContiguousMemorySpecifyCacheNode asigna un intervalo de memoria física contigua y no paginada y la asigna al espacio de direcciones del sistema.
Sintaxis
PVOID MmAllocateContiguousMemorySpecifyCacheNode(
[in] SIZE_T NumberOfBytes,
[in] PHYSICAL_ADDRESS LowestAcceptableAddress,
[in] PHYSICAL_ADDRESS HighestAcceptableAddress,
[in, optional] PHYSICAL_ADDRESS BoundaryAddressMultiple,
[in] MEMORY_CACHING_TYPE CacheType,
[in] NODE_REQUIREMENT PreferredNode
);
Parámetros
[in] NumberOfBytes
Tamaño, en bytes, del bloque de memoria contigua que se va a asignar. Para obtener más información, consulte la sección comentarios de a continuación.
[in] LowestAcceptableAddress
La dirección física válida más baja que puede usar el autor de la llamada. Por ejemplo, si un dispositivo puede dirigir solo las ubicaciones situadas encima de los primeros 8 megabytes del intervalo de direcciones de memoria física del procesador, el controlador de este dispositivo debe establecer Desconteneraddress en 0x0000000000800000.
[in] HighestAcceptableAddress
La dirección física más alta válida que puede usar el autor de la llamada. Por ejemplo, si un dispositivo solo puede abordar ubicaciones en los primeros 16 megabytes del intervalo de direcciones de memoria física del procesador, el controlador de este dispositivo debe establecer HighestAcceptableAddress en 0x0000000000FFFFFF.
[in, optional] BoundaryAddressMultiple
Dirección física múltiple que el búfer asignado no debe cruzar. Una dirección física múltiple siempre debe ser una potencia de dos. Este parámetro es opcional y se puede especificar como cero para indicar que el dispositivo no tiene restricciones especiales de límites de memoria. Para obtener más información, vea Comentarios.
[in] CacheType
Especifica un MEMORY_CACHING_TYPE valor, que indica el tipo de almacenamiento en caché solicitado para la memoria física contigua.
[in] PreferredNode
Número de nodo preferido. Si un sistema de varios procesadores contiene N nodos, los nodos se numeran de 0 a N-1. Si se especifica MM_ANY_NODE_OK o la máquina solo tiene un nodo, la asignación se satisface desde cualquier nodo. De lo contrario, la asignación se realiza desde el nodo preferido o si no se encuentra un intervalo satisfactorio desde el nodo preferido, se devuelve null.
Valor devuelto
MmAllocateContiguousMemorySpecifyCacheNode devuelve la dirección virtual base para la memoria asignada. Si no se puede satisfacer la solicitud, la rutina devuelve NULL.
Observaciones
Un controlador de dispositivo en modo kernel llama a esta rutina para asignar un bloque contiguo de memoria física. En un sistema de multiprocesador de acceso a memoria no uniforme (NUMA), el autor de la llamada puede especificar un nodo preferido desde el que asignar la memoria. Un nodo es una colección de procesadores que comparten acceso rápido a una región de memoria. En un multiprocesador que no es NUMA o en un sistema de un solo procesador, MmAllocateContiguousMemorySpecifyCacheNode trata toda la memoria como perteneciente a un único nodo y asigna memoria de este nodo.
MmAllocateContiguousMemorySpecifyCacheNode asigna un bloque de memoria no paginada que es contiguo en el espacio de direcciones físico. La rutina asigna este bloque a un bloque contiguo de memoria virtual en el espacio de direcciones del sistema y devuelve la dirección virtual de la base de este bloque. La rutina alinea la dirección inicial de una asignación de memoria contigua a un límite de página de memoria.
Los controladores no deben tener acceso a la memoria más allá del tamaño de asignación solicitado. Por ejemplo, los desarrolladores no deben suponer que sus controladores pueden usar memoria de forma segura entre el final de su asignación solicitada y el límite de la página siguiente.
Dado que la memoria física contigua suele estar en breve suministro, debe usarse con moderación y solo cuando sea necesario. Un controlador que debe usar memoria contigua debe asignar esta memoria durante la inicialización del controlador, ya que es probable que la memoria física se fragmente con el tiempo a medida que el sistema operativo asigna y libera memoria. Normalmente, un controlador llama a MmAllocateContiguousMemorySpecifyCacheNode desde su rutina de DriverEntry para asignar un búfer interno para el uso a largo plazo y libera el búfer justo antes de que se descargue el controlador.
La memoria asignada por MmAllocateContiguousMemorySpecifyCacheNode debe liberarse cuando ya no se necesite la memoria. Llame a la rutina MmFreeContiguousMemory para liberar memoria asignada por MmAllocateContiguousMemorySpecifyCacheNode.
Si especifica un valor distinto de cero para el parámetro BoundaryAddressMultiple, el intervalo de direcciones físicos del bloque de memoria asignado no cruzará un límite de dirección que sea un entero múltiplo de este valor. Un controlador debe establecer este parámetro en cero a menos que se requiera un valor distinto de cero para solucionar una limitación de hardware. Por ejemplo, si un dispositivo no puede transferir datos a través de límites físicos de 16 megabytes, el controlador debe especificar un valor de 0x1000000 para este parámetro para asegurarse de que las direcciones que ve el dispositivo no se encapsulan en un límite de 16 megabytes.
Si usa la rutina de MmAllocateContiguousMemorySpecifyCacheNode en equipos con grandes cantidades de memoria, el rendimiento del sistema operativo podría degradarse gravemente cuando el sistema intenta crear un fragmento de memoria contiguo. Esta degradación se reduce considerablemente a partir de Windows Vista SP1 y Windows Server 2008, pero la memoria contigua todavía puede ser costosa de asignar. Por este motivo, los controladores deben evitar llamadas repetidas a MmAllocateContiguousMemorySpecifyCacheNode. En su lugar, los controladores deben asignar todos los búferes contiguos necesarios en sus rutinas de DriverEntry y reutilizar estos búferes.
La memoria que MmAllocateContiguousMemorySpecifyCacheNode asigna no se inicializa. Un controlador en modo kernel primero debe cero esta memoria si va a hacer que sea visible para el software en modo de usuario (para evitar la pérdida de contenido potencialmente con privilegios).
Requisitos
Requisito | Valor |
---|---|
de la plataforma de destino de | Universal |
encabezado de | wdm.h (include Wdm.h, Ntddk.h) |
biblioteca de | NtosKrnl.lib |
DLL de | NtosKrnl.exe |
irQL | IRQL <= DISPATCH_LEVEL |