Maneira correta de corrigir o arquivo de dispositivo ausente em / dev?

0

Estou usando uma placa PCI proprietária da Sensoray na minha máquina Ubunut 14.04 (pretendo atualizar para a versão 18.04 em breve). A placa vem com o código fonte para o driver e um Makefile para construir e instalar o driver. A parte do Makefile relevante para o driver está aqui:

######################################################################
# 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

No final do Makefile, parece que uma vez que o arquivo .ko tenha sido criado, ele simplesmente está sendo copiado para o diretório /lib/modules/$(shell uname -r)/kernel/drivers/sensoray . Existe um script de shell MAKEDEV customizado que está sendo executado para criar os arquivos do dispositivo. Esse script é dado aqui:

#!/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

O problema é que sempre que o sistema é reinicializado. Parece que o driver é carregado corretamente, mas os arquivos do dispositivo em /dev desaparecem. Eu não sei muito sobre o desenvolvimento de drivers, mas pesquisei muito sobre esse problema e encontrei informações conflitantes sobre como obter esses arquivos de dispositivo para serem criados no momento da inicialização. Alguns dizem que criar uma regra do udev é melhor, outros dizem que as regras do udev não devem ser usadas para criar arquivos de dispositivos ausentes ou que o udev não é mais responsável pela criação de arquivos de dispositivos referenciando um novo devtempfs. Minha pergunta é: qual é a maneira correta de corrigir esse problema? Eu tentei a abordagem de regra do udev na qual eu essencialmente chamo o script MAKEDEV customizado da Sensoray, mas isso só funciona se a minha regra não faz referência a nenhuma propriedade específica da placa pci. Por exemplo, a seguinte regra funciona:

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

Esta regra não

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

Parece que não há uevent no tempo de inicialização correspondente à placa pay da Sensoray, que pode ser a raiz do motivo da falta de arquivos de dispositivos. Eu não descobri como registrar o uevents no momento da inicialização para verificar isso. Se as regras do udev são a abordagem correta, eu realmente quero uma regra específica para o cartão e não uma regra genérica que execute o script devido a um uevent de outro dispositivo.

    
por Adam Sperry 28.10.2018 / 09:01

1 resposta

1

Parece muito que o driver personalizado não gera os eventos necessários do udev (é necessário verificar o driver para confirmar isso).

Então a maneira correta seria consertar o driver para gerar os eventos. No caso mais simples, você teria um código semelhante a isso . Em um caso mais complicado, você pode ter regras adicionais do udev que fazem coisas mais complicadas.

Se você não puder ou não quiser modificar o módulo do kernel, IMHO qualquer tipo de solução que funcione é permissível. O ideal seria ter uma dependência que cria o dispositivo quando o módulo é carregado e removê-lo quando ele é descarregado, mas você precisa de eventos do udev para isso (veja acima). Então, a próxima melhor coisa é criá-lo no momento da inicialização, o que significa que eu simplesmente adicionaria um script init.d ou systemd.

Se você puder roubar um evento do udev existente para o seu hardware, isso também funcionará, mas parece que você já tentou e não encontrou um.

    
por 28.10.2018 / 09:52