【问题标题】:open() returns with "No such device" error, but there is such a device (linux)open() 返回“没有这样的设备”错误,但是有这样的设备(linux)
【发布时间】:2009-04-23 18:48:42
【问题描述】:

我正在尝试使用一个有点旧的 DAQ,并且不得不跳过几个环节来获得一个旧的(大约 2004 年)设备驱动程序来编译它 (DTI-DT340 Linux-DAQ-PCI)。

我已经到了编译的地步,我可以加载内核模块,它找到卡,我可以使用 mknod 创建字符设备。

但是当我尝试打开这些设备时,我似乎无法打开这些设备并不断收到errno 19 (ENODEV) 'No such device'

open("/dev/dt340/0",O_RDWR);

但是 mknod 对制作它没有任何抱怨,而且它就在那里:

# ls -l /dev/dt340/
total 0
crw-rw-r-- 1 root staff 250, 0 2009-04-23 11:02 0
crw-rw-r-- 1 root staff 250, 1 2009-04-23 11:02 1
crw-rw-r-- 1 root staff 250, 2 2009-04-23 11:02 2
crw-rw-r-- 1 root staff 250, 3 2009-04-23 11:02 3

有什么我忽略的事情吗?打开失败的原因可能是什么?

这是我用来加载驱动程序和制作设备的脚本。

#!/bin/bash
module="dt340"
device="dt340"
mode="664"

# invoke modprobe with all arguments we were passed
#/sbin/modprobe -t misc -lroot -f -s $module.o $* || exit 1
insmod $module.ko

# remove stale nodes
rm -f /dev/${device}/[0-3]

major=`awk "\\$2==\"$module\" {print \\$1}" /proc/devices`
mkdir -p /dev/${device}
mknod /dev/${device}/0 c $major 0
mknod /dev/${device}/1 c $major 1
mknod /dev/${device}/2 c $major 2
mknod /dev/${device}/3 c $major 3

# give appropriate group/permissions, and change the group
# not all distributions have staff; some have "users" instead
group="staff"
grep '^staff:' /etc/group > /dev/null || group="users"

chgrp $group /dev/${device}/[0-3]
chmod $mode  /dev/${device}/[0-3]

一些附加信息:

#grep dt340 /proc/devices 
250 dt340
# lsmod | grep dt340
dt340                  21516  0 
# tail /var/log/messages
Apr 23 11:59:26 ve kernel: [  412.862139] dt340 0000:03:01.0: PCI INT A -> GSI 22 (level, low) -> IRQ 22
Apr 23 11:59:26 ve kernel: [  412.862362] dt340: In function dt340_init_one:
Apr 23 11:59:26 ve kernel: [  412.862363] Device DT340 Rev 0x0 detected at address 0xfebf0000
#lspci | grep 340
03:01.0 Multimedia controller: Data Translation DT340

回答:printk 确认 -ENODEV 是从 open() 内部抛出的。遵循旧式

while ((pdev = pci_find_device(PCI_VENDOR_ID_DTI, PCI_ANY_ID, pdev)))

(已弃用),if(!pdev) 最终为 true,并返回 -ENODEV。

我越来越近了——我想我必须努力更新 pci 代码以使用更现代的机制...

【问题讨论】:

  • 你用的是udev还是老式的dev?这也会产生影响......
  • 唯一的影响是提示进一步的问题“你为什么要手动创建设备节点?”;否则,没有区别。
  • 驱动使用的是老式开发——这是我第一次深入研究设备驱动,所以我只是想尽可能多地使用已有的驱动

标签: c linux linux-kernel linux-device-driver kernel-module


【解决方案1】:

如果设备显示在 /proc/devices 中,并且您确定 mknod 中的编号正确,则驱动程序本身拒绝打开。驱动程序可以从 open() 返回任何错误代码 - 包括“没有这样的设备”,如果它发现初始化硬件的问题,它可能会返回。

【讨论】:

    【解决方案2】:

    我猜是驱动有问题,检查open函数。

    它显示在 /proc/devices 中,所以所有通用设备的东西似乎都可以。

    【讨论】:

      【解决方案3】:

      mknod 不关心是否存在与给定的主要/次要编号相对应的设备。您确定 insmod 正在安装您的模块吗? lsmod 告诉你什么?

      我不熟悉必须添加“.ko”扩展名。这是您的设备驱动程序特有的吗?

      【讨论】:

      • 添加了上面的 lsmod 信息 - 我认为如果没有加载,我就不会从 /proc/devices 获得那个主要号码。我正在使用 .ko 扩展名,因为我正在将模块加载到我构建它的位置 - 它不在加载模块的标准位置之一。
      • .ko 是自 2.4 以来 Linux 驱动程序通常使用的扩展名 - 较旧的内核使用 .o 但这会导致与不是内核对象的其他对象文件混淆。
      • 嗯,我上一次写内核模块是在 1993 年,那我知道什么?
      • @MarkR - 2.4 仍然使用 .o 模块; .ko 扩展名是在 2.5.51(2002 年 12 月 10 日)中引入的
      【解决方案4】:

      通过 lspci 检查并确保硬件已正确初始化。如果您的系统支持热插拔,pci_find_device 将不起作用。这个问题是一个refcnt。处理和学习的最佳方式是剖析 API。波尔!!

      【讨论】:

        猜你喜欢
        • 2017-03-07
        • 2021-07-01
        • 2014-07-03
        • 2015-06-08
        • 1970-01-01
        • 2017-10-25
        • 1970-01-01
        • 1970-01-01
        • 2021-11-14
        相关资源
        最近更新 更多