Функция MmAllocateContiguousNodeMemory (wdm.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 мб диапазона адресов физической памяти процессора, драйвер для этого устройства должен задать для 0x0000000000800000 значение LowestAcceptableAddress.
[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. |
целевая платформа | Всеобщий |
заголовка | wdm.h (include Wdm.h, Ntddk.h) |
библиотеки | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL |
См. также
MmAllocateContiguousMemorySpecifyCache