简体   繁体   English

将内存从一个内核模块映射到另一个模块中的DMA缓冲区

[英]Remapping memory from one kernel module to a DMA buffer in another module

I am working on a project where module A has a memory buffer that has DMA content and calls module B 's function to perform DMA operation. 我正在一个项目中,其中模块A具有一个具有DMA内容的内存缓冲区,并调用模块B的函数来执行DMA操作。 To simplfy it looks like below: 简单起见,如下所示:

Module A: 模块A:

void get_info()
{
    void *outBuffer = kmalloc(10);
    void *inBuffer = kmalloc(10);

    perform_dma(outBuffer);       // function from module B

    read_output(&inBuffer);      // function from module B
}

Module B: 模块B:

void perform_dma(void *outBuffer)
{
    void *dma_buffer = dma_alloc_coherent()  // <-- allocate a new DMA buffer
    memcpy(dma_buffer, outBuffer, 10);

    do_dma();  // <-- after this is done, dma_buffer has the content module A needs.
}

void read_output(void **inBuffer)
{
    memcpy(*inBuffer, dma_buffer, 10);
}

I understand this might not be efficient but I can't change module B and can use only provided APIs. 我了解这可能并不高效,但我无法更改模块B ,只能使用提供的API。 I am allowed to change B 's perform_dma(void *outBuffer) prototype to perform_dma(void **outBuffer) in best case. 在最佳情况下,我可以将Bperform_dma(void *outBuffer)原型更改为perform_dma(void **outBuffer) It works most of time but in a situation (due to all interrupts/queue events involved in the whole project) I won't be able to call read_output() explicitly and provide an inBuffer to read the content back but can only access outBuffer address after sending it to B . 它大部分时间都有效,但是在某种情况下(由于整个项目中涉及的所有中断/队列事件),我将无法显式调用read_output()并提供inBuffer来读取内容,但只能访问outBuffer地址发送给B之后

Is there a way I can map outBuffer form module A to the dma_buffer allocated in module B to be able to read the output back from same outBuffer ? 有没有办法将模块A的 outBuffer映射到模块B中分配的dma_buffer ,以便能够从同一outBuffer读回输出?

I have figured out that dma_map_single()/dma_unmap_single() work in my case. 我发现dma_map_single()/ dma_unmap_single()在我的情况下有效。 There is no need to change function prototype at all. 根本不需要更改功能原型。 Just use dma_map_single(outBuffer...., DMA_BIDIRECTIONAL) inside perform_dma() to obtain a bus address and pass it to dma controller, so after DMA is done outBuffer would have the content returned from dma controller. 只需在perform_dma()内使用dma_map_single(outBuffer ....,DMA_BIDIRECTIONAL)来获取总线地址并将其传递给dma控制器,因此在完成DMA之后,outBuffer将从dma控制器返回内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM