다음을 통해 공유


System-Space 메모리 할당

중요

이 항목에서 설명하는 ExAllocatePool DDI는 Windows 10 버전 2004에서 더 이상 사용되지 않으며 ExAllocatePool2ExAllocatePool3으로 대체되었습니다. 자세한 내용은 ExAllocatePool2 및 ExAllocatePool3에 사용되지 않는 ExAllocatePool 호출 업데이트를 참조하세요.

드라이버는 디바이스 확장 내에서 시스템 할당 공간을 디바이스별 정보에 대한 전역 스토리지 영역으로 사용할 수 있습니다. 드라이버는 커널 스택만 사용하여 소량의 데이터를 내부 루틴에 전달할 수 있습니다. 일부 드라이버는 일반적으로 I/O 버퍼에 대해 더 많은 양의 시스템 공간 메모리를 추가로 할당해야 합니다.

I/O 버퍼 공간을 할당하기 위해 사용할 가장 좋은 메모리 할당 루틴은 MmAllocateNonCachedMemory, MmAllocateContiguousMemorySpecifyCache, AllocateCommonBuffer(드라이버 디바이스가 버스 master DMA 또는 시스템 DMA 컨트롤러의 자동 초기화 모드를 사용하는 경우) 또는 ExAllocatePoolWithTag입니다.

비페이지 풀은 일반적으로 시스템이 실행될 때 조각화되므로 드라이버의 DriverEntry 루틴은 이러한 루틴을 호출하여 드라이버에 필요한 장기 I/O 버퍼를 설정해야 합니다. ExAllocatePoolWithTag를 제외한 이러한 각 루틴은 최상의 성능을 제공하기 위해 프로세서별 경계(프로세서의 데이터 캐시 라인 크기에 따라 결정됨)에 정렬된 메모리를 할당합니다.

비페이지 풀 메모리는 제한된 시스템 리소스이므로 드라이버는 가능한 한 경제적으로 I/O 버퍼를 할당해야 합니다. 일반적으로 드라이버는 PAGE_SIZE 미만인 각 할당에는 내부적으로 할당을 관리하는 데 사용되는 풀 헤더도 함께 제공되므로 PAGE_SIZE 미만의 할당을 요청하기 위해 이러한 지원 루틴을 반복적으로 호출하지 않아야 합니다.

드라이버 버퍼 공간을 경제적으로 할당하기 위한 팁

I/O 버퍼 메모리를 경제적으로 할당하려면 다음 사항을 알고 있어야 합니다.

  • MmAllocateNonCachedMemory 또는 MmAllocateContiguousMemorySpecifyCache에 대한 각 호출은 요청된 할당의 크기에 관계없이 항상 시스템 페이지 크기의 전체 배수인 비페이지 시스템 공간 메모리를 반환합니다. 따라서 페이지 미만에 대한 요청은 전체 페이지로 반올림되고 페이지의 나머지 바이트는 낭비됩니다. 함수를 호출한 드라이버에서 액세스할 수 없으며 다른 커널 모드 코드에서 사용할 수 없습니다.

  • AllocateCommonBuffer에 대한 각 호출은 하나 이상의 어댑터 개체 맵 레지스터를 사용합니다. 이 레지스터는 하나 이상의 바이트와 최대 한 페이지를 매핑합니다. 맵 레지스터 및 일반적인 버퍼 사용에 대한 자세한 내용은 어댑터 개체 및 DMA를 참조하세요.

ExAllocatePoolWithTag를 사용하여 메모리 할당

드라이버는 PoolType 매개 변수에 대해 다음 시스템 정의 POOL_TYPE 값 중 하나를 지정하여 ExAllocatePoolWithTag를 호출할 수도 있습니다.

  • PoolType = 드라이버가 IRQL > APC_LEVEL 실행되는 동안 액세스할 수 있는 디바이스 확장 또는 컨트롤러 확장에 저장되지 않은 개체 또는 리소스에 대한 NonPagedPool입니다.

    PoolType 값의 경우 ExAllocatePoolWithTag 는 지정된 NumberOfBytes 가 PAGE_SIZE 작거나 같은 경우 요청되는 메모리 양을 할당합니다. 그렇지 않으면 마지막으로 할당된 페이지의 나머지 바이트가 낭비됩니다. 호출자에 액세스할 수 없고 다른 커널 모드 코드에서 사용할 수 없습니다.

    예를 들어 x86에서 5KB(킬로바이트)의 할당 요청은 두 개의 4KB 페이지를 반환합니다. 두 번째 페이지의 마지막 3KB는 호출자 또는 다른 호출자가 사용할 수 없습니다. 비페이지 풀이 낭비되는 것을 방지하려면 드라이버가 여러 페이지를 효율적으로 할당해야 합니다. 예를 들어 이 경우 드라이버는 총 5KB를 할당하기 위해 두 개의 할당(PAGE_SIZE 및 1KB에 대한 할당)을 만들 수 있습니다.

    참고 Windows Vista부터 시스템은 자동으로 추가 메모리를 추가하므로 두 개의 할당이 필요하지 않습니다.

  • PoolType = 항상 IRQL <= APC_LEVEL 액세스되고 파일 시스템의 쓰기 경로에 없는 메모리에 대한 PagedPool입니다.

ExAllocatePoolWithTag 는 요청된 바이트 수를 할당할 수 없는 경우 NULL 포인터를 반환합니다. 드라이버는 항상 반환된 포인터를 검사 합니다. 해당 값이 NULL인 경우 DriverEntry 루틴(또는 NTSTATUS 값을 반환하는 다른 드라이버 루틴)은 STATUS_INSUFFICIENT_RESOURCES 반환하거나 가능한 경우 오류 조건을 처리해야 합니다.