DMA and I / O memory area under Linux

I write this because I have some doubts about the behavior of DMA. I read about the location of PCI and how device drivers interact with the card, and I read about DMA. As I understand it, there is no DMA controller on PCI cards, instead they ask to be the bus master, and then they can receive the DMA address and transfer between the memory and the device (via the bus).

This DMA address is part of the RAM, in fact it is a physical address, and before you do anything, you need to convert it to something that your drivers can use, for example, in the kernel's virtual memory. I checked this with this code:

    /* Virtual kernel address */
    kernel_buff = pci_alloc_consistent(dev, PAGE_SIZE, &dma_addr);

    pr_info("Kernel buffer - %12p , Dma_addr - %12p\n", kernel_buff, (void *)dma_addr );
    pr_info( "Kernelbuffer - dma_addr - %12p\n", kernel_buff - dma_addr);

    strcpy(kernel_buff, "Test dma\n");

    /* Test memory */

    ptest = (void *)dma_addr;
    ptest = phys_to_virt((unsigned long)ptest);

    pr_info("Ptest virtual memory(%p) containts - %s\n", ptest, (char *)ptest);

And the result was:

[425971.835669] Kernel buffer - ffff8800ca70a000 , Dma_addr -     ca70a000
[425971.835671] Kernelbuffer - dma_addr - ffff880000000000
[425971.835673] Ptest virtual memory(ffff8800ca70a000) containts - Test dma

This is how I understood that DMA is part of RAM.

, . , , , , , ? , ?

DMA.

/:

- , :

pci_resource_start

, ? , ? / .

, DMA, / , , ? , ( ) .

+4
1

, , : 1. Assume that you have the data in a buffer. 2. The driver creates a DMA mapping for this buffer(say using pci_alloc_coherent()), and returns the corresponding DMA bus address. 3. This DMA bus address is to be informed to the device. This is done by writing into the correct DMA registers of the device through writel()(Assuming that the device registers are memory mapped). 4. The device also needs to be informed about the amount of data that is being transferred and such (by writing to the appropriate registers of the device using writel()) 4. Now issue the command to the device to start the DMA transactions by writing to one of its control registers(again possibly using writel()). 5. Once the data transaction is completed, the device issues an interrupt. 6. In the interrupt handler, the driver may unallocate the buffer which was used for transaction and might as well perform DMA unmapping.

.. !

IO:

, pci_resource_start(), "" -. . . pci_request_regions(). :

, ?

, ​​ ( ), .

, ?

, , , , , , , , .

. DMA , . , . DMA, . IO .

, .

+5

All Articles