You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ZynqMP平台Linux系统下AXI DMA的BD环强制分配至PL RAM的技术问询

解决方案:确保AXI DMA BD环分配至PL RAM

你的核心问题在于Xilinx AXI DMA驱动默认未从你预留的PL RAM区域分配Buffer Descriptor(BD)环,导致BD位于系统内存,而DMA硬件仅能访问PL RAM,最终造成传输停滞。以下是分步解决方法:

1. 修正预留内存区域的设备树配置

你当前的pl_dma_pool节点设置了no-map属性,这会阻止内核为该区域创建虚拟地址映射,但Xilinx DMA驱动需要访问BD的虚拟地址来管理描述符,因此该属性会迫使驱动 fallback 到系统内存分配BD。

修改reserved-memory节点如下:

reserved-memory {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;
    pl_dma_pool: dma_pool@400000000 {
        compatible = "shared-dma-pool";
        reg = <0x00000004 0x00000000 0x00000000 0x80000000>;
        reusable;
        alignment = <0x1000>;  // 对齐到BD所需的4KB粒度
        size = <0x80000000>;
    };
};

同时删除多余的reserved-mem@400000000节点,避免配置冲突。

2. 确认AXI DMA节点与预留内存的关联

你已经在axi_dma_0及其s2mm通道节点添加了memory-region = <&pl_dma_pool>,这一步是正确的。Xilinx DMA驱动会优先使用设备关联的memory-region进行分配,前提是该区域没有no-map限制。

3. 验证BD环的分配地址

修改设备树后重新编译烧录镜像,启动后可通过以下方式验证BD是否落在PL RAM范围内:

  • 开启内核DEBUG_FS后,查看/sys/kernel/debug/dmaengine/<dma-channel>/下的BD地址信息
  • 在驱动中添加打印,输出BD环的物理地址,确认是否处于0x400000000 - 0x47FFFFFFF区间

4. (可选)修改Xilinx DMA驱动强制从预留内存分配BD

若上述步骤后BD仍未分配到PL RAM,需修改Xilinx DMA驱动代码(drivers/dma/xilinx/xilinx_dma.c),在xilinx_dma_alloc_bd_ring函数中显式使用设备的预留内存区域:

struct device *dev = chan->device->dev;
struct reserved_mem *rmem = dev_get_dma_reserved_mem(dev);
if (rmem) {
    // 从预留内存分配BD环,需自行管理偏移避免冲突
    static u64 bd_offset = 0;
    bd_ring->virt = devm_memremap(dev, rmem->base + bd_offset, size, MEMREMAP_WB);
    bd_ring->phys = rmem->base + bd_offset;
    bd_offset += size;
} else {
    // 回退到默认分配方式
    bd_ring->virt = dma_alloc_coherent(dev, size, &bd_ring->phys, GFP_KERNEL);
}

5. 优化自定义驱动的SG列表处理

你的自定义驱动中手动设置sg_dma_addresssg_dma_len是可行的,但更推荐使用dma_map_sg自动处理,避免手动设置的潜在错误:

int sg_len = dma_map_sg(adev->s2mm->dma_channel->device->dev, 
                        adev->s2mm->sglist, BD_CNT, DMA_DEV_TO_MEM);
if (sg_len != BD_CNT) {
    pr_err("Failed to map SG list\n");
    return -EINVAL;
}

完成上述修改后,重新编译内核和设备树,烧录后BD环的物理地址应落在PL RAM范围内,传输中断也能正常触发。

内容的提问来源于stack exchange,提问作者Дмитрий Кортиков

火山引擎 最新活动