Функция MmAllocateMdlForIoSpace (wdm.h)

Подпрограмма MmAllocateMdlForIoSpace выделяет MDL и инициализирует этот MDL для описания набора диапазонов физических адресов в адресном пространстве ввода-вывода.

Синтаксис

NTSTATUS MmAllocateMdlForIoSpace(
  [in]  PMM_PHYSICAL_ADDRESS_LIST PhysicalAddressList,
  [in]  SIZE_T                    NumberOfEntries,
  [out] PMDL                      *NewMdl
);

Параметры

[in] PhysicalAddressList

Указатель на массив MM_PHYSICAL_ADDRESS_LIST структур, описывающих диапазоны физических адресов для включения в выделенный MDL.

[in] NumberOfEntries

Количество элементов в массиве MM_PHYSICAL_ADDRESS_LIST , на который указывает PhysicalAddressList.

[out] NewMdl

Указатель на расположение, в которое подпрограмма записывает указатель на только что выделенный MDL.

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

MmAllocateMdlForIoSpace возвращает STATUS_SUCCESS в случае успешного выполнения. Возможные возвращаемые значения ошибок включают следующие коды состояния.

Код возврата Описание
STATUS_INVALID_PARAMETER_1 Физический адрес не выравнивается по границе страницы; или диапазон физических адресов не кратен размеру страницы; или диапазон физических адресов используется операционной системой для ОЗУ и недоступен для использования в качестве пространства ввода-вывода.
STATUS_INSUFFICIENT_RESOURCES Недостаточно системных ресурсов для выполнения запрошенной операции.

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

Комментарии

Эта подпрограмма принимает в качестве входного параметра массив MM_PHYSICAL_ADDRESS_LIST структур, описывающих набор физических диапазонов адресов в адресном пространстве ввода-вывода, и выделяет MDL, описывающий эти диапазоны. Последовательные диапазоны физических адресов в массиве не обязательно должны быть смежными.

Диапазоны физических адресов в массиве PhysicalAddressList должны удовлетворять следующим условиям:

  • Базовый физический адрес для каждого диапазона должен быть выровнен по PAGE_SIZE границе в памяти.

  • Размер каждого диапазона в байтах должен быть целым числом, кратным PAGE_SIZE.

  • Все диапазоны физических адресов должны находиться в памяти, доступной для использования в качестве адресного пространства ввода-вывода. Они не могут находиться в памяти, используемой операционной системой для ОЗУ.

  • Общий размер всех диапазонов должен быть меньше 4 гигабайт. В частности, общий размер не должен превышать 2^32–1 байт.

Вызывающий объект отвечает за освобождение выделенного MDL, когда он больше не нужен. Чтобы освободить MDL, вызовите подпрограмму IoFreeMdl . Дополнительные сведения о списках MDL см. в разделе Использование многомерных выражений.

MDL, созданный MmAllocateMdlForIoSpace , не сопоставляется с виртуальной памятью, но может быть передан в подпрограмму, например MapTransferEx , для инициации передачи DMA в диапазоны физической памяти, описанные в MDL, или из нее. Чтобы сопоставить этот MDL с непрерывным диапазоном виртуальных адресов, чтобы процессор смог получить к нему доступ, вызовите подпрограмму MmMapLockedPagesSpecifyCache .

Драйверам доступны только диапазоны физического адресного пространства, которые не зарезервированы операционной системой для использования в качестве памяти. Драйверы используют адресное пространство ввода-вывода для доступа к ресурсам оборудования, сопоставленным в памяти, например к регистрам устройств. При запуске драйвер может получить один или несколько диапазонов физических адресов в качестве преобразованных аппаратных ресурсов. Дополнительные сведения см. в статье Сопоставление Bus-Relative адресов с виртуальными адресами.

В некоторых архитектурах процессора, таких как x86, устройства могут быть сопоставлены с памятью или с адресами портов в специальном адресном пространстве ввода-вывода, выделенном для устройств и отдельном от адресного пространства памяти. Драйверы могут использовать MmAllocateMdlForIoSpace для выделения многомерных выражений только для устройств, сопоставленных в памяти.

Примеры

В следующем примере кода показано, как создать массив MM_PHYSICAL_ADDRESS_LIST структур, описывающих диапазоны физических адресов, которые необходимо включить в выделенный MDL.

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);

В этом примере начальный физический адрес задается переменной BasePhysicalAddress . Число байтов в каждом диапазоне физических адресов задается переменной ChunkSize . Смещение байтов от начала одного физического диапазона до начала следующего определяется переменной Stride . BasePhysicalAddress должны быть выровнены по границе страницы в памяти и ChunkSizeStride должны быть кратными размеру страницы.

Требования

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

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

IoFreeMdl

MDL

MM_PHYSICAL_ADDRESS_LIST

MapTransferEx

MmMapLockedPagesSpecifyCache