我正在尝试使用Linux驱动程序。当前,当我发送事务并开始等待时,我的请求就会超时。我相信这与我在执行DMA映射时设置缓冲区的方式有关。
char *src_dma_buffer = kmalloc(dma_length, GFP_KERNEL);
char *dest_dma_buffer = kzalloc(dma_length, GFP_KERNEL);
tx_dma_handle = dma_map_single(tx_chan->device->dev, src_dma_buffer, dma_length, DMA_TO_DEVICE);
rx_dma_handle = dma_map_single(rx_chan->device->dev, dest_dma_buffer, dma_length, DMA_FROM_DEVICE);在Xilinx的DMA驱动程序中,他们特别注意内存对齐。特别是,它们使用dma_chan->dma_device的一个名为copy_align的属性。
const int dma_length = 16*1024;
len = dmatest_random() % test_buf_size + 1;
len = (len >> align) << align;
if (!len)
len = 1 << align;
src_off = dmatest_random() % (test_buf_size - len + 1);
dst_off = dmatest_random() % (test_buf_size - len + 1);
src_off = (src_off >> align) << align;
dst_off = (dst_off >> align) << align;从dmatest_random()来看,原来的地址完全是随机的。不知道能说些什么/对记忆能做些什么。
static unsigned long dmatest_random(void)
{
unsigned long buf;
get_random_bytes(&buf, sizeof(buf));
return buf;
}然后,他们使用这些偏移设置DMA的源缓冲区和目标缓冲区。
u8 *buf = thread->srcs[i] + src_off;
dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len, DMA_MEM_TO_DEV);我对此感到非常困惑。我唯一的猜测是,它将在虚拟内存中对齐源缓冲区和目标缓冲区的开头。
看看我用kmalloc和kzalloc设置缓冲区的方式,我能保证缓冲区从页面边界开始吗?我说得对吗?我需要缓冲区从页面边界开始吗?
Xilinx测试驱动程序的源代码如下:https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/axidmatest.c
您可以在这里找到我试图解决的问题的高级描述:https://forums.xilinx.com/t5/Embedded-Linux/AXI-DMA-Drivers-for-Kernel-v-4-9-PetaLinux-2017-3/td-p/828917
https://stackoverflow.com/questions/48672908
复制相似问题