OSwhatever wrote:
DMA is a little bit of an outcast in micrkernels where the design of microkernels is a limiting factor for efficiently use DMA. Many times DMA is a part of a driver where you need to setup DMA jobs quickly. If the DMA driver would be a isolated driver in its own process, that would severely degrade the performance as there would a significant delay using the IPC to setup DMA jobs.
I don't think this is an issue. First of all, you're using DMA because the operation you're about to perform is going to be slow, so performance doesn't matter. A little overhead in setting up DMA is not a big deal (compared to the actual peripheral operation's time), plus it only has to be done once, your drivers are going to use the same DMA buffer over and over again.
OSwhatever wrote:
The question is what is a good approach for DMA in such systems. One possibility it to move the DMA driver into the kernel and where it can be operated with system calls which are in general faster than the IPC. Some polite HW DMA blocks might have each channel on mapped separate 4K pages which makes it possible to map each channel in separate processes. However, is this something that can be assumed when you design a system.
What do you think is a good approach for DMA in microkernel systems?
IMHO simply don't care. Use the same way as you would with a monolithic kernel. DMA writes to physical memory, which has to be mapped for the CPU. In a monolithic kernel that's in kernel space. In a microkernel you simply map each buffer in its corresponding task's address space (using a syscall), otherwise everything is the same:
1. the driver starts the operation and blocks,
2. when the peripheral finishes it informs the kernel,
3. the kernel puts the driver into the active queue from the blocked queue
4. the awakened driver task can now read the buffer
AndrewAPrice wrote:
16MB of RAM is not much, so it's possible the first 16MB is already allocated out, so I'd like to keep a map physical memory and which pages are 'pinned' (used for IO and has to be where it is) and 'unpinned'. Unpinned memory can be moved out of the way if we update the owning processes' page tables.
This works, but I use a simpler approach. I simply allocate all the 16Mb as soon as possible, so that my PMM thinks it is used physical memory, and malloc never uses it. Then I pass that entire area to the DMA memory allocator, which then records which parts are allocated to which driver.
Cheers,
bzt