다음을 통해 공유


DMA에서 직접 I/O 사용

다음 그림에서는 I/O 관리자가 직접 I/O를 사용하는 DMA 전송 작업에 대한 IRP_MJ_READ 요청을 설정하는 방법을 보여 줍니다.

dma를 사용하는 디바이스에 대한 사용자 버퍼의 직접 i/O를 보여 주는 다이어그램

이전 그림에서는 드라이버가 IRP의 MdlAddress 를 사용하여 읽기 요청에 대한 데이터를 전송하는 방법을 보여 줍니다. 그림의 드라이버는 패킷 기반 시스템 또는 버스 master DMA를 사용하며 DO_DIRECT_IO 사용하여 디바이스 개체의 Flags를 ORed했습니다.

  1. 사용자 공간 가상 주소의 일부 범위는 현재 스레드의 버퍼를 나타내며, 해당 버퍼의 콘텐츠는 실제로 물리적으로 불협화음이 있는 일부 페이지(이전 그림의 어두운 음영)에 저장될 수 있습니다. I/O 관리자는 이 버퍼를 설명하는 MDL을 만듭니다. MDL은 메모리 관리자가 정의한 불투명 데이터 구조로, 특정 가상 주소 범위를 하나 이상의 페이지 기반 실제 주소 범위에 매핑합니다. 자세한 내용은 MDL 사용을 참조하세요.

  2. I/O 관리자는 스레드가 버퍼를 나타내는 다양한 사용자 공간 가상 주소를 전달하는 현재 스레드의 읽기 요청을 서비스합니다.

  3. I/O 관리자 또는 FSD(파일 시스템 드라이버)는 사용자가 제공한 버퍼에서 접근성을 확인하고 이전에 만든 MDL을 사용하여 MmProbeAndLockPages 를 호출합니다. MmProbeAndLockPages는 MDL의 해당 실제 주소 범위도 채웁니다.

    이전 그림에서 알 수 있듯이 가상 범위에 대한 MDL에는 몇 가지 해당 페이지 기반 실제 주소 항목이 있을 수 있으며, 버퍼의 가상 범위는 MDL에서 설명하는 첫 번째 및 마지막 페이지의 시작부터 일부 바이트 오프셋에서 시작되고 끝날 수 있습니다.

  4. I/O 관리자는 전송 작업을 요청하는 IRP의 MDL(MdlAddress)에 대한 포인터를 제공합니다. 드라이버가 IRP를 완료한 후 I/O 관리자 또는 파일 시스템에서 MmUnlockPages 를 호출할 때까지 MDL에 설명된 실제 페이지는 잠겨 있고 버퍼에 할당된 상태로 유지됩니다. 그러나 IRP가 디바이스 드라이버 또는 디바이스 드라이버 위에 계층화될 수 있는 중간 드라이버로 전송되기 전에도 이러한 MDL의 가상 주소는 보이지 않으며 유효하지 않을 수 있습니다.

  5. 드라이버가 패킷 기반 시스템 또는 버스 master DMA를 사용하는 경우 AdapterControl 루틴은 IRP의 MdlAddress 포인터를 사용하여 MmGetMdlVirtualAddress를 호출하여 MDL의 페이지 기반 항목에 대한 기본 가상 주소를 가져옵니다.

  6. 그런 다음 AdapterControl 루틴은 MmGetMdlVirtualAddress에서 반환된 기본 주소를 사용하여 MapTransfer를 호출하여 디바이스에서 실제 메모리로 직접 데이터를 읽습니다. 자세한 내용은 어댑터 개체 및 DMA를 참조하세요.

드라이버는 항상 버퍼 길이를 검사 합니다. I/O 관리자는 길이가 0인 버퍼에 대한 MDL을 만들지 않습니다.