다음을 통해 공유


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에 사용하는 메모리 공간에 있을 수 없습니다.

  • 모든 범위의 총 크기는 4GB 미만이어야 합니다. 특히 총 크기는 2^32 -1바이트 이상이어야 합니다.

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

MmAllocateMdlForIoSpace 만든 MDL은 가상 메모리에 매핑되지 않지만 mdL에서 설명하는 실제 메모리 범위 간에 DMA 전송을 시작하기 위해 MapTransferEx 같은 루틴에 제공할 수 있습니다. 프로세서에서 액세스할 수 있도록 이 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