Поделиться через


Функция MmAllocateContiguousNodeMemory (ntddk.h)

Подпрограмма MmAllocateContiguousNodeMemory выделяет ряд непрерывной физической памяти и сопоставляет ее с адресным пространством системы.

Синтаксис

PVOID MmAllocateContiguousNodeMemory(
  [in]           SIZE_T           NumberOfBytes,
  [in]           PHYSICAL_ADDRESS LowestAcceptableAddress,
  [in]           PHYSICAL_ADDRESS HighestAcceptableAddress,
  [in, optional] PHYSICAL_ADDRESS BoundaryAddressMultiple,
  [in]           ULONG            Protect,
  [in]           NODE_REQUIREMENT PreferredNode
);

Параметры

[in] NumberOfBytes

Размер выделенного блока непрерывной памяти в байтах. Дополнительные сведения см. в подразделе "Примечания".

[in] LowestAcceptableAddress

Наименьший допустимый физический адрес, который может использовать вызывающий объект. Например, если устройство может обращаться только к расположениям, превышающим первые 8 мб диапазона адресов физической памяти процессора, драйвер для этого устройства должен задать для параметра LowestAcceptableAddress значение 0x0000000000800000.

[in] HighestAcceptableAddress

Максимальный допустимый физический адрес, который может использовать вызывающий объект. Например, если устройство может обращаться только к расположениям в первых 16 мегабайтах диапазона адресов физической памяти процессора, драйвер для этого устройства должен задать для параметра HighestAcceptableAddress значение 0x0000000000FFFFFF.

[in, optional] BoundaryAddressMultiple

Физический адрес, множественный, который не должен пересекать выделенный буфер. Физический адрес, кратный, всегда должен быть двумя. Этот параметр является необязательным и может быть указан как нуль, чтобы указать, что устройство не имеет особых ограничений на границы памяти. Дополнительные сведения см. в подразделе "Примечания".

[in] Protect

Пометки битов, определяющих защиту, используемую для выделенной памяти. Вызывающий объект должен задать один (но не оба) из следующих битов флага в параметре Protect .

Бит флага Значение
PAGE_READWRITE Выделение памяти для чтения и записи без выполнения (NX). Большинство вызывающих абонентов должны установить этот бит флага. Дополнительные сведения см. в подразделе "Примечания".
PAGE_EXECUTE_READWRITE Выделение исполняемой памяти для чтения и записи. Этот бит флага следует задавать только в том случае, если вызывающей объекту требуется возможность выполнения инструкций в выделенной памяти.

Кроме того, вызывающий объект может задать один (но не оба) из следующих необязательных битов флага в параметре Protect .

Бит флага Значение
PAGE_NOCACHE Выделение памяти без кэширования. Этот бит флага похож на вызов MmAllocateContiguousMemorySpecifyCache с параметром CacheType , равным MmNonCached.
PAGE_WRITECOMBINE Выделение объединенной памяти для записи. Этот бит флага аналогичен вызову MmAllocateContiguousMemorySpecifyCache с параметром CacheType , равным MmWriteCombined.

Если ни PAGE_NOCACHE, ни PAGE_WRITECOMBINE не указаны, выделенная память полностью кэшируется. В этом случае этот эффект аналогичен вызову MmAllocateContiguousMemorySpecifyCache с параметром CacheType , равным MmCached.

[in] PreferredNode

Номер предпочтительного узла. Если многопроцессорная система содержит N узлов, узлы нумеруются от 0 до N-1. Если вызывающий объект задает для PreferredNode значение MM_ANY_NODE_OK, подпрограмма выбирает узел для выделения памяти. В противном случае, если память в указанном диапазоне адресов не может быть выделена из предпочтительного узла, подпрограмма возвращает значение NULL.

Возвращаемое значение

MmAllocateContiguousNodeMemory возвращает базовый виртуальный адрес выделенной памяти. Если запрос не может быть выполнен, подпрограмма возвращает ЗНАЧЕНИЕ NULL.

Комментарии

Драйвер устройства в режиме ядра вызывает эту подпрограмму для выделения непрерывного блока физической памяти. Вызывающий драйвер может указать, следует ли использовать память без выполнения (NX) для выделения. В многопроцессорной системе с неоднородным доступом к памяти (NUMA) вызывающий объект может указать предпочтительный узел для выделения памяти. Узел — это коллекция процессоров, которые совместно используют быстрый доступ к области памяти. В многопроцессорной или однопроцессорной системе, отличной от NUMA, MmAllocateContiguousNodeMemory рассматривает всю память как принадлежащая одному узлу и выделяет память из этого узла.

MmAllocateContiguousNodeMemory выделяет блок несмежной памяти, который является смежным в физическом адресном пространстве. Подпрограмма сопоставляет этот блок с непрерывным блоком виртуальной памяти в системном адресном пространстве и возвращает виртуальный адрес базы этого блока. Подпрограмма выравнивает начальный адрес непрерывного выделения памяти по границе страницы памяти.

Драйверы не должны получать доступ к памяти, превышающей запрошенный размер выделения. Например, разработчикам не следует предполагать, что их драйверы могут безопасно использовать память между окончанием запрошенного выделения и следующей границей страницы.

Так как непрерывной физической памяти обычно не хватает, ее следует использовать экономно и только при необходимости. Драйвер, который должен использовать непрерывную память, должен выделять эту память во время инициализации драйвера, так как физическая память, скорее всего, будет фрагментирована со временем, так как операционная система выделяет и освобождает память. Как правило, драйвер вызывает MmAllocateContiguousNodeMemory из своей подпрограммы DriverEntry , чтобы выделить внутренний буфер для долгосрочного использования, и освобождает буфер непосредственно перед выгрузкой драйвера.

Память, выделенная MmAllocateContiguousNodeMemory , должна быть освобождена, если память больше не нужна. Вызовите подпрограмму MmFreeContiguousMemory , чтобы освободить память, выделенную MmAllocateContiguousNodeMemory.

MmAllocateContiguousNodeMemory похож на процедуру MmAllocateContiguousMemorySpecifyCacheNode . В отличие от MmAllocateContiguousMemorySpecifyCacheNode, MmAllocateContiguousNodeMemory можно использовать для выделения памяти без выполнения (NX). Рекомендуется выделить драйверу память NX, если драйверу явно не требуется возможность выполнения инструкций в выделенной памяти. Выделяя память NX, драйвер повышает безопасность, предотвращая выполнение вредоносными программами инструкций в этой памяти. Память, выделенная подпрограммами MmAllocateContiguousMemory, MmAllocateContiguousMemorySpecifyCache и MmAllocateContiguousMemorySpecifyCacheNode , всегда является исполняемой.

Если указать ненулевое значение для параметра BoundaryAddressMultiple , физический диапазон адресов выделенного блока памяти не будет пересекать границу адреса, которая является целым числом, кратным этому значению. Драйвер должен задать для этого параметра нулевое значение, если для обхода аппаратного ограничения не требуется ненулевое значение. Например, если устройство не может передавать данные через физические границы 16 МЕГАБАЙТ, драйвер должен указать значение 0x1000000 для этого параметра, чтобы гарантировать, что адреса, видимые устройством, не будут обтекаться вокруг границы в 16 МЕГАБАЙТ.

Память, выделенная MmAllocateContiguousNodeMemory , не инициализирована. Драйвер режима ядра должен сначала обнулить эту память, если он собирается сделать ее видимой для программного обеспечения в пользовательском режиме (чтобы избежать утечки потенциально привилегированного содержимого).

Требования

Требование Значение
Минимальная версия клиента Доступно начиная с Windows 8.
Целевая платформа Универсальное
Верхняя часть ntddk.h (включая Wdm.h, Ntddk.h)
Библиотека NtosKrnl.lib
DLL NtosKrnl.exe
IRQL IRQL <= DISPATCH_LEVEL

См. также раздел

DriverEntry

MmAllocateContiguousMemory

MmAllocateContiguousMemorySpecifyCache

MmAllocateContiguousMemorySpecifyCacheNode

MmFreeContiguousMemory