I'm writing this because I have some doubts about the behaviour of DMA. I'm reading about the PCI layout and how the device drivers interacts with the card, and I read about DMA. Since I understood, PCI cards doesn't have a DMA controller, instead of that they request to be a master of the bus, and then they are able to take a DMA address and do transfers between memory and device ( through the bus ).
This DMA address is a portion of RAM, actually it's a physical address and before do nothing you need to convert that in something that your drivers can use, like a kernel virtual memory. I've checked that 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 output 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 a portion of RAM.
My doubt is about how this transfer is made. I mean, every time that I write in this buffer, the data that the buffer constains will be transfered to the device? Or only the adress of the memory location, and then the device will read from this location?
This is about DMA.
And about I/O memory maps:
When we request a I/O memory region of the device with for example:
pci_resource_start
We are requesting the region of the memory where device's registers is located? So in this way we have this memory location into the RAM ? And we wan write/read as a normal memory locations.
And the final point is that, we use DMA because the I/O memory mapping only allows few bytes per cycle since this process involves the CPU, right? So we can transfer amounts of data between memory locations( RAM and bus of device) without the cpu.
Direct memory access, or DMA, is the advanced topic that completes our overview of memory issues. DMA is the hardware mechanism that allows peripheral components to transfer their I/O data directly to and from main memory without the need for the system processor to be involved in the transfer.
So that Linux can use the dynamic DMA mapping, it needs some help from the drivers, namely it has to take into account that DMA addresses should be mapped only for the time they are actually used and unmapped after the DMA transfer. The following API will work of course even on platforms where no such hardware exists.
Not exactly. DMA is when two devices that aren't the CPU use the memory bus to communicate (with one device usually being main memory, and the process being orchestrated by the CPU). Memory-mapped IO is the CPU talking to device on the memory bus that is not main memory.
Many devices can temporarily take control of the bus and perform data transfers to (and from) main memory or other devices. Because the device is doing the work without the help of the CPU, this type of data transfer is known as direct memory access (DMA).
The steps involved to transfer the data to the device could be summarized as follows :
pci_alloc_consistent()
or the newer dma_alloc_coherent()
), and returns the corresponding DMA bus address.writel()
(assuming that the device registers are memory mapped).writel()
)writel()
).And there you have it.. The data is transferred to the device!
Now coming to the question regarding the IO memory maps :
First of all when we call pci_resource_start()
, we do not "request" the IO ports. This is the way by which we are just gathering info. about the ports. The request is done using pci_request_regions()
. To be specific to your questions :
We are requesting the region of the memory where device's registers is located?
Using this, we are requesting the kernel to give access to this region of memory (memory mapped ports) where the device's registers are located.
So in this way we have this memory location into the RAM ?
No, we do not have this memory location in RAM, it is only memory mapped, which means that the device shares the same address, data and control lines with the RAM and hence, same instruction that are used to access the RAM can also be used to access the device registers.
You've answered your last question yourself. DMA provides huge amounts to data to be transferred efficiently. But, there are cases where you need to use the memory mapping to transfer the data. The best example is already stated in the explanation of DMA transaction process, where, you need to transfer the address and control information to the device. This could be done only through memory mapped IO.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With