Comment attribuer un pilote USB au périphérique

30

Cette question est double:

Tout d'abord, comment détacher manuellement un pilote d'un périphérique USB et en connecter un autre? Par exemple, j'ai un appareil qui, lorsqu'il est connecté, utilise automatiquement le pilote de stockage USB.

sortie usbview

Vendor Id: xxxx
Product Id: xxxx
...
    Number of Interfaces: 2
    Interface Number: 0
        Name: usb-storage
        Number of Endpoints: 2
        ...
    Interface Number: 1
        Name: (none)
        Number of Endpoints: 2
        ...

Je ne veux pas utiliser le pilote de stockage USB, donc dans mon application, j'utilise la libusbbibliothèque pour détacher le pilote de stockage USB, puis je revendique l'interface. Je peux ensuite envoyer des données vers et depuis les applications exécutées sur mon périphérique USB et sur mon système Linux hôte.

Comment détacher un pilote manuellement en dehors d'une application?


Deuxièmement, comment attribuer automatiquement le pilote à attacher au plug-in de périphérique? J'ai actuellement une configuration de règle udev pour définir automatiquement les autorisations de l'appareil:

SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"

Puis-je utiliser les règles udev pour affecter des pilotes à des interfaces spécifiques sur le périphérique USB? Par exemple, si je voulais que le module usbnet soit utilisé automatiquement sur l'interface 0 au lieu du stockage USB, est-ce possible dans udev?

linsek
la source
1
Si une partie du problème est le chargement du module de droite, voir Webcam sur Angström
Gilles 'SO- arrête d'être méchant'
1
Avez-vous besoin du module de stockage USB? sinon, vous pouvez le mettre dans une liste noire et il ne se chargera pas du tout.
Hanan N.
@Gilles, j'ai réussi à charger le LKM. Ma question est de savoir comment attacher cela manuellement et automatiquement à l'appareil?
linsek
@Hanan, actuellement je n'ai aucune utilité pour le module de stockage USB. Je pourrais finir par avoir besoin de le mettre sur liste noire pour attacher automatiquement le bon module, mais j'ai d'abord besoin de savoir comment attacher le port USB.
linsek
1
Le module @njozwiak usbnetne se charge pas automatiquement, car il ne contient aucune information sur le matériel, qui peut l'utiliser. Essayez de trouver le pilote approprié et utilisez-le, par exemple modinfo kalmia. Dans les aliaslignes, vous verrez l'identifiant du fournisseur xxxx et l'identifiant du produit yyyy comme usb:vxxxxpyyyy. Ou vous pouvez éditer le fichier /lib/modules/kernel_version/modules.usbmap et pour votre matériel, vous pouvez supprimer la ligne, où se trouve pour vous le module USB de stockage HW ou modifier le stockage USB avec le pilote réseau approprié. Mais après depmod -ace changement s'en ira ...
Jan Marek

Réponses:

20

Pour la première partie de la question, j'ai cherché et je n'ai pas pu trouver une meilleure façon de détacher un pilote USB que ce que vous faites déjà avec libusb.

Quant à la deuxième partie de la question, udev peut réagir au chargement du pilote, mais ne pas forcer l' affectation d'un pilote spécifique à un périphérique.

Chaque pilote du noyau Linux est responsable d'un ou plusieurs périphériques. Le pilote lui-même choisit les périphériques qu'il prend en charge. Il le fait par programme, c'est-à-dire en vérifiant le fournisseur et l'ID du produit de l'appareil, ou, si ceux-ci ne sont pas disponibles (par exemple un ancien appareil), en effectuant des heuristiques d'auto-détection et des vérifications d'intégrité. Une fois que le conducteur est convaincu d'avoir trouvé un appareil qu'il prend en charge, il s'y attache. En bref, vous ne pouvez souvent pas forcer un pilote particulier à utiliser un périphérique particulier. Parfois, cependant, un pilote de périphérique est généreux avec ce qu'il accepte, et un périphérique peut fonctionner qu'il ne connaît pas. Votre kilométrage variera! Dans le passé, j'ai dû ajouter manuellement des ID de périphérique / fournisseur PCI étranges aux pilotes qui devraient les prendre en charge, avec un succès mitigé et quelques plantages du noyau amusants.

Maintenant, dans le cas des modules, il y a une étape supplémentaire. Le chargeur de module est réveillé par le noyau lorsqu'un nouveau périphérique est détecté. Il a passé une chaîne de «modalias», qui identifie le périphérique et ressemble à ceci pour les périphériques USB:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

Cette chaîne contient la classe de périphérique ( usb) et les informations spécifiques à la classe (fournisseur / périphérique / numéro de série, classe de périphérique, etc.). Chaque pilote de noyau contient une ligne telle que:

MODULE_ALIAS("usb:...")

Qui doivent correspondre aux usbalias (les caractères génériques sont utilisés pour faire correspondre plusieurs appareils). Si le modaliascorrespond à celui pris en charge par le pilote, ce pilote est chargé (ou averti du nouveau périphérique, s'il est déjà là).

Vous pouvez voir les appareils pris en charge (par modalias) et leurs modules associés avec

less /lib/modules/`uname -r`/modules.alias

Si vous recherchez le pilote de périphérique de stockage USB, vous verrez qu'il a certains périphériques spécifiques qu'il prend en charge par le fournisseur et l'ID de périphérique, et tentera également de prendre en charge tout périphérique avec la bonne classe (de stockage), quel que soit le fournisseur / périphérique .

Vous pouvez influencer cela en utilisant des mécanismes d'espace utilisateur sur votre système d'exploitation ( /etc/modprobe.d/sur Debian et ses amis). Vous pouvez blacklister les modules, ou vous pouvez spécifier les modules à charger par les modalias, tout comme le modules.aliasfichier (et en utilisant la même syntaxe). depmod -arégénérera alors les modèles du chargeur de module.

Cependant, même si vous pouvez conduire ce cheval à l'eau, mais vous ne pouvez pas le faire boire. Si le pilote ne prend pas en charge votre appareil, il doit l'ignorer.

Telle est la théorie dans le cas général.

En pratique, et dans le cas de l'USB, je vois que votre appareil semble avoir deux interfaces , dont le stockage est une. Le noyau s'attachera à l' interface de stockage de l'ensemble du périphérique. Si l'autre interface a la bonne classe, le usbnetpilote pourrait s'y attacher. Oui, vous pouvez avoir plusieurs pilotes connectés au même périphérique physique , car un périphérique USB exporte plusieurs interfaces (par exemple, mon clavier Logitech G15 en exporte deux car il possède un périphérique clavier et un écran LCD, chacun étant géré par un pilote distinct) .

Le fait que la deuxième interface de votre périphérique USB ne soit pas détectée indique un manque de support dans le noyau. Quel que soit le cas, vous pouvez répertorier les interfaces / points de terminaison de l'appareil avec des détails atroces en utilisant lsusb -v | less, puis faites défiler vers le bas jusqu'à votre appareil particulier (vous pouvez limiter la sortie par appareil: ID du fournisseur ou chemin USB si vous le souhaitez).

Veuillez noter: je simplifie un peu trop ici la structure logique des périphériques USB. Blâmez le consortium USB. :)

Alexios
la source
4
Il y en a déjà static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);dans le code, est-il redondant avec les modalias?
Thomas
Dans mon cas, ces lignes sont générées automatiquement par une magie Makefile n'importe où dans le pilote. C'est pourquoi j'ai ajouté trois fois les lignes de MODULE_ALIAS mais il n'est jamais répertorié. Quoi qu'il en soit, merci pour le lsusb -v. avec ça je pouvais le vérifier et trouver la faille dans mon idée. J'ai ensuite récupéré la source pour un identifiant connu et trouvé le tableau avec les entrées que je devais manipuler.
JackGrinningCat