2

ARM 아키텍처의 DMA 내부를 이해하려고합니다. 커널 설명서를 참조하십시오 : http://lxr.free-electrons.com/source/Documentation/DMA-API-HOWTO.txt.dma_map_single internals on arm archtecture

커널 공간 (DMA 제약 조건)에 메모리를 할당하고 dma_map_single() 함수에 전달하면이 함수는 DMA 요구 (쓰기 결합 또는 비 캐시)에 따라 메모리의 매핑 특성을 변경합니다. 그런 다음 플랫폼이 IOMMU를 지원하면 장치 버스의 가상 주소를 반환하거나 장치에서 직접 액세스 할 수있는 실제 주소를 반환합니다.

올바른 이해가 있습니까?

현재 소스 코드를 매핑 할 수 없으므로 코드 스 니펫이있는 포인터가 도움이 될 것입니다.

답변

5

아닙니다.

스트리밍 DMA API (즉, dma_map_*()/dma_unmap_*())의 경우 실제로는 다시 매핑되지 않습니다. 커널 선형 매핑의 주소 (즉, 일반 kmalloc() 메모리) 만 스트리밍 DMA에 유효하기 때문에 CPU 매핑이 캐시 가능하므로 비 동기화 장치에 대한 dma_map_*() 작업은 버퍼의 범위에 따라 캐시를 정리/무효화합니다 해당 dma_unmap_*()까지는 CPU에 액세스하지 않아야합니다. 그런 다음 CPU가 디바이스에 의해 메모리에 기록 된 데이터를 읽을 수 있기 전에 캐시를 다시 무효화하십시오 (추측 적으로 페치가 발생하는 경우). 캐시 - 코 히어 런트 디바이스의 경우, 그 중 아무 것도 필요하지 않으므로 건너 뜁니다.

버퍼가 선형 맵에 있기 때문에 DMA 주소는 왠지 복잡한 하드웨어 (예 : Raspberry Pi 2)의 실제 메모리와 버스 주소간에 변환 할 장치 별 오프셋을 뺀 오프셋 virt_to_phys()의 간단한 경우입니다./3 또는 TI Keystone 2) - 예를 참조하십시오. the ARM implementation of dma_map_page() (그 중 dma_map_single() is merely a special case)입니다. IOMMU가 관련되어있는 경우, 해당 실제 주소에 대한 IOVA 매핑을 작성하고 기본 버스 주소 대신 해당 IOVA를 반환하는 추가 단계가 있습니다. 일관된 DMA의 API (즉, dma_alloc_coherent()) 장치가 자체 - 코 히어 런트 캐시 할 때, 우리는가 위해 vmalloc 영역에 할당 된 페이지의 개별 비 캐시 매핑을 생성 할 를 들어, 다음 사용하는 것이

주 스트리밍 DMA와 달리 CPU와 장치가 언제든지 일관된 버퍼에 액세스 할 수 있으므로 선형 캐시 별칭을 정리하기위한 몇 가지 초기 캐시 유지 관리 후 해당 버퍼에 대한 모든 CPU 액세스에 대해 캐시 불가능 별칭을 사용합니다.

+0

감사합니다. 나는 코드를 검사했다. pfn_to_bus는 말한대로 실제 주소로 pfn을 변환하지만, 적용되는 버스 오프셋을 볼 수 없다. #define __pfn_to_bus (x) __pfn_to_phys (x). 내가 놓친 게 있니? – shunty

+0

@shunty ['pfn_to_dma()'] (http://lxr.free-electrons.com/source/arch/arm/include/asm/dma-mapping.h?v4.7#L54)가 필요합니다. – Notlikethat

+0

'pfn - = dev-> dma_pfn_offset;' 이 dma_pfn_offset은 장치에 특정한 것입니까? 장치 구성 중에 초기화됩니까? – shunty

관련 문제