修复 /dev 中丢失的设备文件的正确方法?

修复 /dev 中丢失的设备文件的正确方法?

我在我的 Ubunut 14.04 机器上使用 Sensoray 的专有 PCI 卡(我打算很快升级到 18.04)。该卡附带驱动程序的源代码以及用于构建和安装驱动程序的 Makefile。 Makefile 中与驱动程序相关的部分位于此处:

######################################################################
# for kernel modeule level driver:

# Kernel directory
KDIR        := /lib/modules/$(shell uname -r)/build
# Module directory
MODDIR      := /lib/modules/$(shell uname -r)/kernel/drivers/sensoray

# System values
PWD     := $(shell pwd)
KERNEL_24   := $(if $(wildcard $(KDIR)/Rules.make),1,0)

# Target file
obj-m       := s626.o


# Source files
ifeq    ($(KERNEL_24),0) # > 2.4
s626-objs   := s626drv.o 
else # <= 2.4
s626-objs   := s626drv.o
endif

.PHONY:     all clean modules_install

ifeq    ($(KERNEL_24),0) # > 2.4
ifeq    ($(KERNELRELEASE),)
all:
        $(MAKE) -C $(KDIR) M=$(PWD) SUBDIRS=$(PWD)
clean modules_install:
        $(MAKE) -C $(KDIR) M=$(PWD) SUBDIRS=$(PWD) $@
endif   # KERNELRELEASE

else    # <= 2.4

ifneq   ($(KERNELRELEASE),)

include $(KDIR)/Rules.make

s626.o: $(s626-objs)
        $(Q)$(LD) $(LD_RFLAG) -r -o $@ $(s626-objs)
else

all:
        $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
        rm -f *.ko *.o .*.cmd .*.o.flags *.mod.c

endif   # KERNELRELEASE

endif   # KERNEL_24

ifeq    ($(KERNEL_24),1) # <= 2.4

install:        s626.o
    @if [ -d /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/ ];\
    then rm -f /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/s626.*;\
    fi
    @if [ -d /lib/modules/$(shell uname -r)/extra/ ];\
    then rm -f /lib/modules/$(shell uname -r)/extra/s626.*;\
    fi
    su -c "set -x;./MAKEDEV;mkdir -p $(MODDIR);cp -v s626.o $(MODDIR);depmod -a"

else
install:        s626.ko
    @if [ -d /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/ ];\
    then rm -f /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/s626.*; \
    fi
    @if [ -d /lib/modules/$(shell uname -r)/extra/ ];\
    then rm -f /lib/modules/$(shell uname -r)/extra/s626.*;\
    fi
    @if [ -d /lib/modules/$(shell uname -r)/kernel/drivers/staging/comedi/drivers ];\
    then rm -f /lib/modules/$(shell uname -r)/kernel/drivers/staging/comedi/drivers/s626.*;\
    fi
    su -c "set -x;./MAKEDEV;mkdir -p $(MODDIR);cp -v s626.ko $(MODDIR);install -m 444 s626.ko $(MODDIR);depmod -a"
endif  # KERNEL > 2.4

在 Makefile 的末尾,看起来文件一旦.ko创建,就被简单地复制到/lib/modules/$(shell uname -r)/kernel/drivers/sensoray目录中。还有一个正在执行的自定义 MAKEDEV shell 脚本来创建设备文件。该脚本在这里给出:

#!/bin/bash

function makedev () {

    for dev in 0 1 2 3; do
        echo "/dev/$1$dev: char $2 $dev"
        rm -f /dev/$1$dev
        mknod /dev/$1$dev c $2 $dev
        chmod 666 /dev/$1$dev
    done

    # symlink for default device
    rm -f /dev/$1
    ln -s /dev/${1}0 /dev/$1
}

makedev s626a 146

问题是每当系统重新启动时。看起来驱动程序已正确加载,但设备文件/dev消失了。我对驱动程序开发了解不多,但我对这个问题进行了很多研究,并且发现了有关如何在启动时创建这些设备文件的相互冲突的信息。有人说创建 udev 规则是最好的,有人说 udev 规则不应该用于创建丢失的设备文件,或者 udev 不再负责引用新的 devtempfs 的设备文件创建。我的问题是:解决这个问题的正确方法是什么?我尝试过 udev 规则方法,其中我本质上是从 Sensoray 调用自定义 MAKEDEV 脚本,但这仅在我的规则未引用 pci 卡的任何特定属性时才有效。例如,以下规则有效:

ACTION=="add", SUBSYSTEM=="pci", RUN+="/home/kpopek/MAKEDEV"

这条规则不

ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1131", RUN+="/home/kpopek/MAKEDEV"

启动时似乎没有任何uevent与Sensoray pci卡匹配的东西,这可能是设备文件丢失的根源。我还没有弄清楚如何uevents在启动时记录以验证这一点。如果 udev 规则是正确的方法,我真的想要一个特定于卡的规则,而不是由于uevent来自其他设备而恰好运行脚本的通用规则。

答案1

看起来自定义驱动程序没有生成所需的 udev 事件(必须查看驱动程序才能确认这一点)。

所以恰当的方法是修复驱动程序以生成事件。在最简单的情况下,您的代码类似于。在更复杂的情况下,您可以使用额外的 udev 规则来执行更复杂的操作。

如果您不能或不想修改内核模块,恕我直言,任何可行的解决方案都是允许的。理想情况下,您希望有一个依赖项,在加载模块时创建设备,并在卸载模块时删除它,但您需要 udev 事件(见上文)。因此,下一个最好的办法是在启动时创建它,这意味着我只需添加一个 init.d 或 systemd 脚本。

如果您可以劫持硬件的现有 udev 事件,那也很好,但看起来您已经尝试过但没有找到。

相关内容