ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

【Linux】RK3568-NPU加载失败问题(九)

【Linux】RK3568-NPU加载失败问题(九) RK3568 NPU开发板100ASK DShanPI R1系统Armbian v26.11 rolling内核6.1.172-vendor-rk35xx目标启用 NPU为 RKNN 模型推理做准备一句话总结新版驱动不再创建 /dev/rknpu 在/dev/dri/card*主设备NPU 问题的本质是 IOMMU 抢占了 NPU 寄存器地址第一章背景与核心概念1.1 为什么需要启用 NPURK3568 的 NPU1 TOPS INT8默认在设备树里是禁用状态内核虽然编译了驱动rknpu.ko但硬件节点未激活。因此需要加载 Device Tree Overlay 来打开这个开关。1.2 IOMMU 是什么IOMMUInput/Output Memory Management Unit是硬件级的设备内存管家功能说明地址转换设备用虚拟地址IOMMU 翻译成物理地址访问保护防止设备越权访问内存类比IOMMU 就像设备的门卫翻译员。1.3 核心冲突问题根源NPU 寄存器范围 0xfde40000 ─────────────────────── 0xfde4ffff │ IOMMU 地址 0xfde4b000 ↑ 落在 NPU 范围中间问题链条Linux 启动时IOMMU 驱动先 probe占用0xfde4b000NPU 驱动后 probe想申请整块0xfde40000-0xfde4ffff内核发现0xfde4b000已被占用 → 拒绝 → 报cant request region解决方案禁用 NPU 的 IOMMU让 NPU 用非 IOMMU 模式工作。1.4 DRM 是什么DRMDirect Rendering Manager是 Linux 内核管理图形/计算设备的子系统。项目说明设备节点/dev/dri/card*主设备、/dev/dri/renderD*渲染设备NPU 为什么用它新版本 RKNPU 驱动改用 DRM 框架通过renderD129暴露接口关键结论新版驱动不再创建/dev/rknpu而是用/dev/dri/card/dev/dri/renderD129。一直找/dev/rknpu是走了弯路。1.5 社区验证Armbian 论坛开发者fero在 ODROID-M1同为 RK3568遇到相同问题将 NPU 的 IOMMU 节点改为disabled后NPU 正常工作成功跑通 YOLOv5 RKNN Demo。第二章问题诊断2.1 典型错误日志dmesg|grep-irknpu|head-15输出RKNPU fde40000.npu: rknpu iommu is enabled, using iommu mode ← IOMMU 启用中 RKNPU fde40000.npu: cant request region for resource [mem 0xfde40000-0xfde4ffff] ← 寄存器申请失败 RKNPU fde40000.npu: error -ENXIO: IRQ npu_irq not found ← 中断名找不到 [drm] Initialized rknpu 0.9.8 20240828 for fde40000.npu on minor 1 ← DRM 已注册2.2 错误解读错误信息含义根因iommu is enabledIOMMU 占用地址IOMMU 驱动先加载cant request regionNPU 寄存器申请失败地址被 IOMMU 占用IRQ npu_irq not found中断名找不到设备树缺interrupt-names2.3 辅助诊断命令# 检查 NPU 设备节点预期不存在ls-l/dev/rknpu# 查看 DRM 渲染节点ls-l/dev/dri/# 查看 accel 子系统新内核可能使用ls-l/dev/accel/# 查看 NPU 内存映射cat/proc/iomem|grep-ifde4# 查看中断分配cat/proc/interrupts|grep-inpu\|fde4# 查看内核是否含 rknpu 驱动greprknpu /usr/lib/modules/$(uname-r)/modules.builtin第三章解决方案自写 Overlay3.1 Overlay 四个 Fragment 的作用Fragment作用关键属性0在/reserved-memory下创建 128MB 预留区size 0x00 0x8000000 128MB1把预留区挂到 NPU 节点memory-region引用 0 标签2补充中断名interrupt-names npu_irq3禁用 IOMMU核心修复解决cant request region3.2 下载 Radxa 官方 Overlay可选用代理# 直连会 SSL 错误wgethttps://raw.githubusercontent.com/radxa-pkg/radxa-overlays/main/arch/arm64/boot/dts/rockchip/overlays/rk3568-npu-enable.dts# 用 ghproxy.net 代理推荐wgethttps://ghproxy.net/https://raw.githubusercontent.com/radxa-pkg/radxa-overlays/main/arch/arm64/boot/dts/rockchip/overlays/rk3568-npu-enable.dts3.3 安装 Overlaysudoarmbian-add-overlay npu-enable-fix.dtsarmbian-add-overlay自动完成编译.dts→.dtbo复制到/boot/overlay-user/修改/boot/armbianEnv.txt添加user_overlays3.4 断电重启关键sudoshutdown-hnow⚠️ 必须彻底断电等屏幕完全黑、SSH 断开手动拔电源等30 秒再插电原因reserved-memory需在内核启动极早期划定软重启可能无法正确重置硬件。第四章验证 NPU 启用4.1 加入 render 组用户权限sudousermod-a-Gvideo,render$USERexit# 退出 SSH 重连重连后验证groups# 应看到 video 和 render4.2 检查设备节点ls-l/dev/dri/预期输出crw-rw---- 1 root video 226, 0 card0 crw-rw---- 1 root render 226, 128 renderD128 ← 显示控制器 crw-rw---- 1 root render 226, 129 renderD129 ← NPU crw-rw---- 1 root render 226, 130 renderD130 ← GPU4.3 检查内核日志最关键dmesg|grep-irknpu|head-10成功标志OF: reserved mem: initialized node rknpu RKNPU fde40000.npu: RKNPU: rknpu iommu is disabled, using non-iommu mode ← 核心 RKNPU fde40000.npu: assigned reserved memory node rknpu RKNPU fde40000.npu: RKNPU: initialize reserved memory for rknpu device! [drm] Initialized rknpu 0.9.8 20240828 for fde40000.npu on minor 1失败标志对比RKNPU fde40000.npu: rknpu iommu is enabled, using iommu mode RKNPU fde40000.npu: cant request region for resource [...] RKNPU fde40000.npu: error -ENXIO: IRQ npu_irq not found4.4 检查 NPU 硬件信息sudocat/sys/kernel/debug/rknpu/version# RKNPU driver: v0.9.8sudocat/sys/kernel/debug/rknpu/freq# 900000000900 MHzsudocat/sys/kernel/debug/rknpu/load# NPU load: 0%sudocat/sys/kernel/debug/rknpu/volt# 950000950 mVsudocat/sys/kernel/debug/rknpu/power# off空闲省电推理时开启4.5 验证成功标志汇总检查项成功标志内核日志iommu is disabled, using non-iommu mode错误消失不再有cant request region和IRQ npu_irq not found设备节点/dev/dri/renderD129存在驱动版本v0.9.8频率900 MHz第五章完整代码流程按顺序执行5.1 创建 Overlay 文件# 创建目录mkdir-p~/my-overlayscd~/my-overlays# 创建并写入 Overlay 文件nanonpu-enable-fix.dts //// NPU 启用修复 OverlayRK3568 / DShanPI R1 // 作用解决 IOMMU 抢占 NPU 寄存器地址 中断名缺失问题 // 安装sudo armbian-add-overlay npu-enable-fix.dts //// 声明 DTS 文件版本为1设备树源文件的固定格式 /dts-v1/;// 声明这是叠加层Overlay不是完整设备树而是对现有设备树的补丁 // 没有这一行dtc 会把它当成完整设备树来编译导致错误 /plugin/;// 根节点开始所有 fragment 都挂在根节点下 /{// -------------------------------------------------------- // fragment0为 NPU 分配 128MB 预留内存 // 目的NPU 驱动需要一块专用的连续物理内存DMA 区 // -------------------------------------------------------- fragment0{// 目标节点路径/reserved-memory系统预留内存池 // 这里用 target-path 按路径定位而不是用 target 按标签引用 target-path/reserved-memory;// __overlay__ 里写要叠加进目标节点的内容 __overlay__{// 定义一个名为 rknpu 的子节点标签为 rknpu_reserved // 这个标签在后面 fragment1 里用rknpu_reserved 引用 rknpu_reserved: rknpu{// 声明这是共享 DMA 内存池NPU 驱动通过这个类型识别 // 内核启动时会初始化这块预留区不分配给普通程序 compatibleshared-dma-pool;// 标记为非活跃系统不主动使用这块内存 // 只有被设备NPU引用时才真正生效 inactive;// 标记为可回收系统内存紧张时可以回收这块内存 // 避免 2GB 内存浪费 128MB 长期占用 reusable;// 预留内存大小0x8000000 字节128MB // 格式高位 低位64位系统用两个32位数表示 // 0x08000000134217728字节128MB size0x00 0x8000000;// 内存起始地址对齐要求0x10004096字节4KB // 保证预留区起始地址按页对齐满足 NPU DMA 要求 alignment0x00 0x1000;};};};// -------------------------------------------------------- // fragment1把预留内存挂到 NPU 节点 // 目的让 NPU 驱动知道该用哪块预留内存 // -------------------------------------------------------- fragment1{// 目标节点NPU 设备节点 target-path/npufde40000;__overlay__{// 引用 fragment0 定义的预留区rknpu_reserved 是标签 // NPU 驱动初始化时会读取这个属性找到专用的 DMA 内存区 memory-regionrknpu_reserved;};};// -------------------------------------------------------- // fragment2给 NPU 节点补充中断名称 // 目的解决IRQ npu_irq not found错误 // 原因驱动代码用 platform_get_irq_byname(dev,npu_irq)// 按名字查找中断但设备树里只有 interrupts 没有 interrupt-names // -------------------------------------------------------- fragment2{// 目标节点NPU 设备节点和 fragment1 是同一个节点 target-path/npufde40000;__overlay__{// 定义中断名称必须与驱动代码里查找的字符串完全一致 // 驱动源码里用的是npu_irq所以这里也写npu_irq// 名字写错一样会报IRQ xxx not foundinterrupt-namesnpu_irq;};};// -------------------------------------------------------- // fragment3禁用 NPU 的 IOMMU核心修复 // 目的解决cant request region for resource错误 // 原因NPU 寄存器范围 0xfde40000-0xfde4ffff 包含了 // IOMMU 地址 0xfde4b000IOMMU 先 probe 会抢占该地址 // NPU 后 probe 时申请失败 // 禁用 IOMMU 后NPU 用非 IOMMU 模式工作直接用物理地址 // -------------------------------------------------------- fragment3{// 目标节点NPU 的 IOMMU 设备节点 target-path/iommufde4b000;__overlay__{// 把状态改成disabled内核不再初始化这个 IOMMU 设备 // 原来是okay改成disabled后驱动跳过 probe // 副作用NPU 失去 IOMMU 的内存访问保护但推理功能不受影响 statusdisabled;};};};5.2 编译并安装 Overlay# 删除旧的 dtbo避免冲突sudorm-f/boot/overlay-user/npu-enable-fix.dtbo# 编译并安装cd~/my-overlayssudoarmbian-add-overlay npu-enable-fix.dts输出预期Compiling the overlay Copying the compiled overlay file to /boot/overlay-user/ Reboot is required to apply the changes5.3 确认配置写入# 检查 armbianEnv.txtcat/boot/armbianEnv.txt|grepuser_overlays# 应输出user_overlaysnpu-enable-fix# 检查 dtbo 文件存在ls-lh/boot/overlay-user/npu-enable-fix.dtbo5.4 彻底断电重启# 先正常关机sudoshutdown-hnow# 等 10 秒屏幕完全黑# 手动拔掉开发板电源# 等 30 秒# 重新插电启动5.5 用户权限配置# 加入 video 和 render 组sudousermod-a-Gvideo,render$USER# 退出 SSHexit# 重新 SSH 连接后验证groups5.6 验证 NPU4 项检查# 检查1内核日志最关键dmesg|grep-irknpu|head-10# 成功标志iommu is disabled, using non-iommu mode# 检查2DRM 设备节点ls-l/dev/dri/# 成功标志存在 renderD129# 检查3NPU 驱动版本sudocat/sys/kernel/debug/rknpu/version# 成功标志RKNPU driver: v0.9.8# 检查4NPU 工作频率sudocat/sys/kernel/debug/rknpu/freq# 成功标志900000000第六章常见命令速查6.1 查看系统自带 Overlayls/boot/dtb/rockchip/overlay/6.2 检查驱动加载# 内核是否含 rknpugreprknpu /usr/lib/modules/$(uname-r)/modules.builtin# 输出kernel/drivers/rknpu/rknpu.ko# lsmod内置模块不显示lsmod|greprknpu6.3 检查设备树# NPU 节点状态cat/sys/firmware/devicetree/base/npufde40000/status# 输出okay# NPU 节点属性ls/proc/device-tree/npufde40000/6.4 检查内存与中断# 寄存器区域cat/proc/iomem|grep-ifde4# 中断分配cat/proc/interrupts|grep-inpu\|fde4第七章关键经验总结7.1 三个不要误区真相❌ 不要找/dev/rknpu✅ 新版驱动用/dev/dri/renderD129❌ 不要只看设备节点✅ 必须看dmesg是否iommu is disabled❌ 不要软重启✅ 必须断电重启才能让 reserved-memory 生效7.2 三个必须必须原因✅ 必须禁用 IOMMU否则 NPU 无法申请寄存器区域✅ 必须补中断名驱动按名字查中断缺interrupt-names会失败✅ 必须加预留内存NPU 需要专用连续内存区7.3 修复前后对比项目修复前修复后IOMMU 模式enableddisabled, non-iommu mode寄存器申请cant request regionassigned reserved memory中断注册IRQ npu_irq not found正常设备节点无/dev/dri/renderD129核心结论NPU 问题的本质是IOMMU 抢占了 NPU 寄存器地址。解决方案是通过 Overlay禁用 NPU 的 IOMMU、补全中断名、添加预留内存然后断电重启。验证成功的关键是dmesg里出现iommu is disabled, using non-iommu mode。
返回列表