2009-12-03 3 views
3

kmalloc (sizeof (my_struct_t), GFP_ATOMIC)을 사용하여 나중에 일부 장치의 DMA 컨트롤러를 사용하여 데이터 전송에 사용되는 메모리를 할당하는 Linux 커널 (2.6.18) . 나중에 my_struct의 크기를 늘려야했습니다. 너무 커지기 때문에 kmalloc() 코드는 정적 어설 션을 사용하고 __you_cannot_kmalloc_that_much 심볼을 컴파일하여 메모리 덩어리가 너무 커서 할당 할 수 없다는 것을 알립니다. 그래서 나는 my_struct_t를 정적 변수로 선언 할 것이고 그것을 전혀 할당 할 필요가 없을 것이라고 생각했다.DMA 용 정적 데이터 구조 사용

정의 됨 static my_struct_t my_struct;

하지만 DMA 트랜잭션이 제대로 작동하지 않아 유효하지 않은 데이터 DMA가 버퍼에 저장되었습니다.

제 질문은 : dma에 정적 (전역) 버퍼를 사용하는 것이 금지되어 있습니까? 그리고 그렇다면 커널 메모리 맵에 정확히 어디에 버퍼가 있는지 찾아보십시오.

감사

답변

2

일반적으로 오래된 메모리는 사용할 수 없으며 DMA 용으로 사용할 수 없습니다. 문제는 메모리 영역이 페이지 경계를 넘을 수 있으며 실제 메모리의 여러 영역으로 분할 될 수 있다는 것입니다. 또한 스왑 아웃되어 나중에 이전과 다른 실제 위치로 다시 스왑됩니다. 일부 아키텍처에서는 장치 버스에서 전혀 볼 수없는 메모리 영역이 있습니다. 때때로 부적절하게 획득 한 DMA 버퍼가 작동하기 때문에 운이 좋을 수도 있지만 보장되지는 않습니다.

dma_alloc_coherent()과 같은 dma 할당 기능을 확인하십시오. 또한 LDD3 15 장.

너무 커서 DMA 버퍼를 할당하는 데 문제가있는 경우 DMA 전송을 수동으로 분할하거나 분산 형 수집 DMA를 사용해야하는 또 다른 문제가 있습니다.

2

문제는 당신이 스택에 메모리를 할당하는 경우 메모리가 메모리의 연속 된 물리적 블록에 있음을 보장 할 수 없습니다 올 것이다. 그렇지 않다면 DMA를 할 수 없습니다.

kmalloc 할 수있는 여러 블록으로 DMA 전송을 중단하는 것이 쉽지 않을까요? 그러면 DMA 전송을 단 1 개 대신 전송할 수 있습니다. 현재 사용하고있는 것과는 달리 버스 활용도에 별다른 차이가 없으며 작동 할 것입니다.

+0

실제로 스택에 할당하지 않습니다. 커널 모듈의 일부 데이터 섹션에 할당 된 전역 변수를 사용합니다. 섹션이 커널 메모리에로드됩니다.이 섹션은 계속 앉아 있고 dma'able memory라고 가정합니다. 커널 메모리가 커널 메모리에로드 될 때 실제 진행되는 작업에 대해 더 자세히 설명 할 수 있습니까 –

+0

실제 RAM에 여전히 할당되지 않을 가능성이 있습니다. 일반적으로 프로그램은 가상 메모리에로드되므로 더 이상 블록이 연속적임을 보장 할 수 없습니다. – Goz