Функция 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 |