为何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
相关产品推荐
相关产品推荐

