Функция 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
должны быть выровнены по границе страницы в памяти и ChunkSize
Stride
должны быть кратными размеру страницы.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Доступно начиная с Windows 8. |
Целевая платформа | Универсальное |
Верхняя часть | wdm.h (включая Wdm.h) |
Библиотека | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL |