You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何system-user.dtsi定义两个DMA中断,/proc/interrupts仅显示一个?

UIO驱动下DMA双中断仅显示一个的问题排查

问题描述

我在Vivado中完成了DMA传输设计,计划通过UIO设备驱动。当前系统已存在/dev/uio0设备及/sys/class/uio/uio0/maps/map0目录。我将PL侧的两个DMA中断添加到了system-user.dtsi文件中,内容如下:

/include/ "system-conf.dtsi"
/ {
    chosen {
            bootargs = "earlycon clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio rootwait quiet loglevel=0";
            stdout-path = "serial0:115200n8";
        };
};

&axi_dma_0 {
    clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk";
    clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>;
    interrupt-names = "mm2s_introut", "s2mm_introut";
    compatible = "generic-uio";
    reg = <0x40400000 0x10000>;
    interrupt-parent = <&intc>;
    interrupts = <0 29 4 0 30 4>;
};

但通过Petalinux构建启动镜像并启动板卡后,/proc/interrupts中仅显示一条中断条目:

32:          0          0 GIC-0  61 Level     dma

我推测61对应mm2s中断(61-32=29),但对应30号的s2mm中断为何没有出现?

补充信息

  • 本地Petalinux项目目录执行dmesg | grep -C3 dma的输出:
[    0.179479] APIC: Switch to symmetric I/O mode setup
[    0.179481] DMAR: Host address width 36
[    0.179483] DMAR: DRHD base: 0x000000fed90000 flags: 0x1
[    0.179488] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap c9008020660262 ecap f0105a
[    0.179490] DMAR: RMRR base: 0x000000ded2e000 end: 0x000000ded3cfff
[    0.179492] DMAR-IR: IOAPIC id 2 under DRHD base  0xfed90000 IOMMU 0
[    0.179493] DMAR-IR: HPET id 0 under DRHD base 0xfed90000
--
[    0.529581] system 00:03: [io  0x0a30-0x0a4f] has been reserved
[    0.529584] system 00:03: [io  0x0a00-0x0a0f] has been reserved
[    0.529773] system 00:04: [io  0x04d0-0x04d1] has been reserved
[    0.530002] pnp 00:05: [dma 0 disabled]
[    0.530295] system 00:07: [mem 0xfed1c000-0xfed1ffff] has been reserved
[    0.530298] system 00:07: [mem 0xfed10000-0xfed17fff] has been reserved
[    0.530299] system 00:07: [mem 0xfed18000-0xfed18fff] has been reserved
  • 板端执行该命令无输出;QSPI启动板卡的日志如下:
SF: Detected s25fl256s1 with page size 256 Bytes, erase size 64 KiB, total 32 MiB
device 0 offset 0x9c0000, size 0x40000
SF: 262144 bytes @ 0x9c0000 Read: OK
QSPI: Trying to boot script at 3000000
## Executing script at 03000000
Wrong image format for "source" command
QSPI: SCRIPT FAILED: continuing...
JTAG: Trying to boot script at 3000000
## Executing script at 03000000
Wrong image format for "source" command
JTAG: SCRIPT FAILED: continuing...
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
3016 bytes read in 16 ms (183.6 KiB/s)
## Executing script at 03000000
Trying to load boot images from qspi
SF: Detected s25fl256s1 with page size 256 Bytes, erase size 64 KiB, total 32 MiB
device 0 offset 0xa80000, size 0x1500000
SF: 22020096 bytes @ 0xa80000 Read: OK
Wrong Image Format for bootm command
ERROR: can't get kernel image!
Booting using Fit image failed
device 0 offset 0xa00000, size 0x600000
SF: 6291456 bytes @ 0xa00000 Read: OK
device 0 offset 0x1000000, size 0xf80000
SF: 16252928 bytes @ 0x1000000 Read: OK
Wrong Image Format for bootm command
ERROR: can't get kernel image!
Booting using Separate images failed
Trying to load boot images from jtag
Wrong Image Format for bootm command
ERROR: can't get kernel image!
Trying to load boot images from mmc0
17834024 bytes read in 1655 ms (10.3 MiB/s)
## Loading kernel from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Verifying Hash Integrity ... OK
   Trying 'kernel-1' kernel subimage
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x1000010c
     Data Size:    4654376 Bytes = 4.4 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x00200000
     Entry Point:  0x00200000
     Hash algo:    sha256
     Hash value:   1cf7ebde3d2e20e4297f3bb94fd5b62628d7a00343786bd751f76bab9335fbf9
   Verifying Hash Integrity ... sha256+ OK
## Loading ramdisk from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Verifying Hash Integrity ... OK
   Trying 'ramdisk-1' ramdisk subimage
     Description:  petalinux-image-minimal
     Type:         RAMDisk Image
     Compression:  uncompressed
     Data Start:   0x10475524
     Data Size:    13157774 Bytes = 12.5 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    sha256
     Hash value:   6acad62316441a792f0dc018eb8fdfa293b6358057f648e5a5484309e7d100b5
   Verifying Hash Integrity ... sha256+ OK
## Loading fdt from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Verifying Hash Integrity ... OK
   Trying 'fdt-system-top.dtb' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x10470740
     Data Size:    19734 Bytes = 19.3 KiB
     Architecture: ARM
     Hash algo:    sha256
     Hash value:   da2cb926234ba4ea5339484c96b5f02f265fa00d2f6e8b50f1bf21d7c9113506
   Verifying Hash Integrity ... sha256+ OK
   Booting using the fdt blob at 0x10470740
Working FDT set to 10470740
   Loading Kernel Image
   Loading Ramdisk to 2f373000, end 2ffff58e ... OK
   Loading Device Tree to 2f36b000, end 2f372d15 ... OK
Working FDT set to 2f36b000

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 6.1.5-xilinx-v2023.1 (oe-user@oe-host) (arm-xilinx-linux-gnueabi-gcc (GCC) 12.2.0, GNU ld (GNU Binutils) 2.39.0.20220819) #1 SMP PREEMPT Fri Apr 21 07:47:58 UTC 2023
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt: Machine model: xlnx,zynq-7000
earlycon: cdns0 at MMIO 0xe0001000 (options '115200n8')
printk: bootconsole [cdns0] enabled
INIT: version 3.04 booting
Starting udev
Starting version 251.8+
hwclock: can't open '/dev/misc/rtc': No such file or directory
Fri Mar  9 12:34:56 UTC 2018
hwclock: can't open '/dev/misc/rtc': No such file or directory
Configuring packages on first boot....
 (This may take several minutes. Please do not power off the machine.)
Running postinst /etc/rpm-postinsts/100-sysvinit-inittab...
update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing)
 Removing any system startup links for run-postinsts ...
  /etc/rcS.d/S99run-postinsts
INIT: Entering runlevel: 5
Configuring network interfaces... udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting discover
udhcpc: broadcasting discover
udhcpc: no lease, forking to background
done.
Starting OpenBSD Secure Shell server: sshd
  generating ssh RSA host key...
  generating ssh ECDSA host key...
  generating ssh ED25519 host key...
done.
Starting rpcbind daemon...done.
starting statd: done
hwclock: can't open '/dev/misc/rtc': No such file or directory
Starting internet superserver: inetd.
NFS daemon support not enabled in kernel
Starting syslogd/klogd: done
Starting tcf-agent: OK

问题原因与解决方法

1. 核心原因

uio_pdrv_genirq驱动默认仅注册第一个中断,如果设备需要多个中断,必须在设备树中显式声明中断数量,否则驱动会忽略后续中断。

2. 设备树修正

修改&axi_dma_0节点,添加uio,num_of_irq = <2>;属性,告知UIO驱动需要注册2个中断:

&axi_dma_0 {
    clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk";
    clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>;
    interrupt-names = "mm2s_introut", "s2mm_introut";
    compatible = "generic-uio";
    reg = <0x40400000 0x10000>;
    interrupt-parent = <&intc>;
    interrupts = <0 29 4 0 30 4>;
    uio,num_of_irq = <2>;  // 新增该行,指定中断数量
};

3. 验证步骤

  • 重新构建设备树与Petalinux镜像,烧录后重启板卡。
  • 查看/proc/interrupts,应能看到对应62(30+32)的s2mm中断条目。
  • 检查UIO设备中断信息:
    cat /sys/class/uio/uio0/irq/0
    cat /sys/class/uio/uio0/irq/1
    
    确认两个中断均已注册。

4. 额外排查点

  • 确认Vivado中DMA的两个中断已正确连接到PS的INTC控制器,硬件设计无错误。
  • 检查内核配置是否开启CONFIG_UIO_PDRV_GENIRQ,确保UIO驱动已编译进内核。
  • 板端dmesg无DMA日志是因为loglevel=0屏蔽了输出,可临时修改bootargs为loglevel=7,重启后查看驱动加载日志,确认UIO驱动是否正确识别双中断。

内容的提问来源于stack exchange,提问作者Creator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:44:58