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


Функция 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, созданный 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 должны быть выровнены по границе страницы в памяти, а ChunkSize и Stride должны иметь несколько размеров страницы.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Доступно начиная с Windows 8.
целевая платформа Всеобщий
заголовка wdm.h (include Wdm.h)
библиотеки NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL

См. также

IoFreeMdl

MDL

MM_PHYSICAL_ADDRESS_LIST

MapTransferEx

MmMapLockedPagesSpecifyCache