Asignar memoria System-Space
Importante
Los DDIs exAllocatePool descritos en este tema han quedado en desuso en Windows 10, versión 2004 y se han reemplazado por ExAllocatePool2 y ExAllocatePool3. Para obtener más información, consulte Actualización de llamadas exAllocatePool en desuso a ExAllocatePool2 y ExAllocatePool3.
Los controladores pueden usar espacio asignado por el sistema dentro de sus extensiones de dispositivo como áreas de almacenamiento globales para información específica del dispositivo. Los controladores solo pueden usar la pila del kernel para pasar pequeñas cantidades de datos a sus rutinas internas. Algunos controladores tienen que asignar cantidades adicionales y mayores de memoria del espacio del sistema, normalmente para búferes de E/S.
Para asignar espacio de búfer de E/S, las mejores rutinas de asignación de memoria que se usarán son MmAllocateNonCachedMemory, MmAllocateContiguousMemorySpecifyCache, AllocateCommonBuffer (si el dispositivo del controlador usa DMA de bus-master o un modo de inicialización automática de un controlador DMA del sistema) o ExAllocatePoolWithTag.
Normalmente, el grupo no paginado se fragmenta a medida que se ejecuta el sistema, por lo que la rutina DriverEntry de un controlador debe llamar a estas rutinas para configurar los búferes de E/S a largo plazo que necesite el controlador. Cada una de estas rutinas, excepto ExAllocatePoolWithTag, asigna memoria alineada en un límite específico del procesador (determinado por el tamaño de la línea de caché de datos del procesador) para proporcionar el mejor rendimiento.
Los controladores deben asignar búferes de E/S lo más económica posible, ya que la memoria del grupo no paginada es un recurso del sistema limitado. Normalmente, un controlador debe evitar llamar a estas rutinas de soporte técnico repetidamente para solicitar asignaciones de menos de PAGE_SIZE porque cada asignación que es menor que PAGE_SIZE también viene con un encabezado de grupo que se usa para administrar internamente la asignación.
Sugerencias para asignar espacio de búfer de controladores económicamente
Para asignar memoria de búfer de E/S económicamente, tenga en cuenta lo siguiente:
Cada llamada a MmAllocateNonCachedMemory o MmAllocateContiguousMemorySpecifyCache siempre devuelve un múltiplo completo del tamaño de página del sistema, de memoria del espacio del sistema no paginado, independientemente del tamaño de la asignación solicitada. Por lo tanto, las solicitudes de menos de una página se redondean a una página completa y se desperdician los bytes restantes de la página; Son inaccesibles por el controlador que llamó a la función y no se pueden usar con otro código en modo kernel.
Cada llamada a AllocateCommonBuffer usa al menos un registro de mapa de objetos de adaptador, que asigna al menos un byte y al menos una página. Para obtener más información sobre los registros de mapa y el uso de búferes comunes, vea Objetos del adaptador y DMA.
Asignación de memoria con ExAllocatePoolWithTag
Los controladores también pueden llamar a ExAllocatePoolWithTag, especificando uno de los siguientes valores de POOL_TYPE definidos por el sistema para el parámetro PoolType :
PoolType = NonPagedPool para los objetos o recursos que no se almacenan en una extensión de dispositivo o extensión de controlador a la que el controlador puede tener acceso mientras se ejecuta en IRQL > APC_LEVEL.
Para este valor PoolType , ExAllocatePoolWithTag asigna la cantidad de memoria que se solicita si el numberOfBytes especificado es menor o igual que PAGE_SIZE. De lo contrario, se desperdician los bytes restantes de la última página asignada: no se puede acceder al autor de la llamada y no se puede usar mediante otro código en modo kernel.
Por ejemplo, en un x86, una solicitud de asignación de 5 kilobytes (KB) devuelve dos páginas de 4 KB. Los últimos 3 KB de la segunda página no están disponibles para el autor de la llamada u otro llamador. Para evitar perder el grupo no paginado, el controlador debe asignar varias páginas de forma eficaz. En este caso, por ejemplo, el controlador podría realizar dos asignaciones, una para PAGE_SIZE y otra para 1 KB, para asignar un total de 5 KB.
Nota A partir de Windows Vista, el sistema agrega automáticamente la memoria adicional para que dos asignaciones no sean necesarias.
PoolType = PagedPool para la memoria a la que siempre se accede en IRQL <= APC_LEVEL y no está en la ruta de acceso de escritura del sistema de archivos.
ExAllocatePoolWithTag devuelve un puntero NULL si no puede asignar el número solicitado de bytes. Los controladores siempre deben comprobar el puntero devuelto. Si su valor es NULL, la rutina DriverEntry (o cualquier otra rutina de controlador que devuelva valores NTSTATUS) debe devolver STATUS_INSUFFICIENT_RESOURCES o controlar la condición de error si es posible.