1. 第一现场DMA_CHANNEL_NPRIV 是怎么冒出来的1.1 一次 DMA 通道申请失败的真实日志先给个最典型的现场。嵌入式 Linux 板卡开机外设驱动音频、SPI、UART、存储控制器都常见在 probe 阶段请求 DMA 通道紧跟着 dmesg 里滚出一行类似这样的东西[ 3.245678] dma-pl330 fdb30000.dma-controller: DMA_CHANNEL_NPRIV [ 3.245712] spi1 1f0000.spi: failed to request DMA channel rx, err-16如果是不带完整 dmesg 的全志/RK 系列 BSP可能更简单就一行 error没有 errno也没有 caller stack。很多人第一次看到DMA_CHANNEL_NPRIV会下意识先去搜 errno 表结果-EINVAL、-EBUSY、-EPERM都对不上因为这不是标准内核 errno而是某个 DMA 控制器驱动或者厂商 BSP 自定义的错误码。我在 RK 平台的 BSP 和 Zynq 平台的 FPGA 加速卡项目里都见过类似的报错每次出现都差不多是同一个画面外设 probe 走到一半DMA 通道拿不到整个设备直接 init 失败或者降级成 PIO 模式。这篇文章就是把这类问题的机制、排查方法和修复手段一次讲透适合做嵌入式 Linux 驱动、BSP、FPGADMA 集成、音视频采集卡相关工作的同学参考。如果你只是写应用层代码大概率不会碰它一旦碰了说明内核驱动这一层已经出问题了。1.2 名字拆解DMA_CHANNEL_NPRIV 的两个可能含义先拆一下这个字符串。DMA 是 Direct Memory AccessCHANNEL 指 DMA 控制器里的通道剩下的NPRIV是矛盾的焦点。我在不同板子上看到两种含义都存在第一种是not private指 DMA 通道的“独占属性”不满足。Linux dmaengine 里本来就有DMA_PRIVATE能力位表示这个通道是给某个固定外设专用的不能随便给别的设备共享。第二种是not privileged指通道的“权限级别”不够。在带安全隔离的 SoC 上DMA 通道可能被配置成 secure / non-secure如果发起 DMA 的驱动进程或者 IOMMU 域没有