MmAllocateMdlForIoSpace 함수(wdm.h)

MmAllocateMdlForIoSpace 루틴은 MDL을 할당하고 이 MDL을 초기화하여 I/O 주소 공간의 실제 주소 범위 집합을 설명합니다.

구문

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

매개 변수

[in] PhysicalAddressList

할당된 MDL에 포함할 실제 주소 범위를 설명하는 MM_PHYSICAL_ADDRESS_LIST 구조체 배열에 대한 포인터입니다.

[in] NumberOfEntries

PhysicalAddressList가 가리키는 MM_PHYSICAL_ADDRESS_LIST 배열의 요소 수입니다.

[out] NewMdl

루틴이 새로 할당된 MDL에 대한 포인터를 쓰는 위치에 대한 포인터입니다.

반환 값

성공하면 MmAllocateMdlForIoSpace 가 STATUS_SUCCESS 반환합니다. 가능한 오류 반환 값에는 다음 상태 코드가 포함됩니다.

반환 코드 설명
STATUS_INVALID_PARAMETER_1 실제 주소는 페이지 경계에 맞지 않습니다. 또는 실제 주소 범위가 페이지 크기의 배수가 아닌 경우 또는 실제 주소 범위는 운영 체제에서 RAM용으로 사용되며 I/O 공간으로 사용할 수 없습니다.
STATUS_INSUFFICIENT_RESOURCES 요청된 작업을 수행할 수 있는 시스템 리소스가 부족합니다.

이전 오류 반환 코드 목록이 완전하다고 가정하지 마세요. 루틴은 목록에 표시되지 않는 오류 코드를 반환할 수 있습니다.

설명

이 루틴은 입력 매개 변수로 I/O 주소 공간의 실제 주소 범위 집합을 설명하는 MM_PHYSICAL_ADDRESS_LIST 구조의 배열을 허용하고 이러한 범위를 설명하는 MDL을 할당합니다. 배열의 연속된 물리적 주소 범위는 연속할 필요가 없습니다.

PhysicalAddressList 배열의 실제 주소 범위는 다음 조건을 충족해야 합니다.

  • 각 범위에 대한 기본 물리적 주소는 메모리의 PAGE_SIZE 경계에 맞춰야 합니다.

  • 각 범위의 크기(바이트)는 PAGE_SIZE 정수 배수여야 합니다.

  • 모든 실제 주소 범위는 I/O 주소 공간으로 사용할 수 있는 메모리에 있어야 합니다. RAM용 운영 체제에서 사용하는 메모리 공간에 있을 수 없습니다.

  • 모든 범위의 총 크기는 4기가바이트 미만이어야 합니다. 특히 총 크기는 2^32 - 1바이트를 초과하면 안됩니다.

호출자는 할당된 MDL이 더 이상 필요하지 않을 때 해제할 책임이 있습니다. MDL을 해제하려면 IoFreeMdl 루틴을 호출합니다. MDL에 대한 자세한 내용은 MDL 사용을 참조하세요.

MmAllocateMdlForIoSpace에서 만든 MDL은 가상 메모리에 매핑되지 않지만 MapTransferEx와 같은 루틴에 제공하여 MDL에서 설명하는 실제 메모리 범위 간에 DMA 전송을 시작할 수 있습니다. 프로세서에서 액세스할 수 있도록 이 MDL을 인접한 범위의 가상 주소에 매핑하려면 MmMapLockedPagesSpecifyCache 루틴을 호출합니다.

메모리로 사용하기 위해 운영 체제에서 예약하지 않은 물리적 주소 공간의 범위만 드라이버에서 I/O 주소 공간으로 사용할 수 있습니다. 드라이버는 I/O 주소 공간을 사용하여 디바이스 레지스터와 같은 메모리 매핑 하드웨어 리소스에 액세스합니다. 드라이버가 시작되면 변환된 하드웨어 리소스로 하나 이상의 물리적 주소 범위를 수신할 수 있습니다. 자세한 내용은 가상 주소에 Bus-Relative 주소 매핑을 참조하세요.

x86과 같은 일부 프로세서 아키텍처에서는 디바이스가 메모리 매핑되거나 디바이스 전용이고 메모리 주소 공간과 분리된 특수 I/O 주소 공간의 포트 주소에 매핑될 수 있습니다. 드라이버는 MmAllocateMdlForIoSpace 를 사용하여 메모리 매핑된 디바이스에 대해서만 MDL을 할당할 수 있습니다.

예제

다음 코드 예제에서는 할당된 MDL에 포함할 실제 주소 범위를 설명하는 MM_PHYSICAL_ADDRESS_LIST 구조의 배열을 생성하는 방법을 보여 줍니다.

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