So weisen Sie dem Gerät einen USB-Treiber zu

30

Diese Frage ist zweifach:

Wie kann man einen Treiber manuell von einem USB-Gerät trennen und einen anderen anschließen? Ich habe zum Beispiel ein Gerät, das bei einer Verbindung automatisch den USB-Speichertreiber verwendet.

usbview ausgang

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

Ich möchte den USB-Speichertreiber nicht verwenden, daher verwende ich in meiner Anwendung die libusbBibliothek, um den USB-Speichertreiber zu trennen, und beanspruche dann die Schnittstelle. Ich kann dann Daten an und von den Anwendungen senden, die auf meinem USB-Gerät und auf meinem Host-Linux-System ausgeführt werden.

Wie kann ein Treiber außerhalb einer Anwendung manuell getrennt werden?


Zweitens, wie ordne ich den Treiber automatisch dem Geräte-Plugin zu? Ich habe derzeit eine udev-Regel eingerichtet, um die Geräteberechtigungen automatisch festzulegen:

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

Kann ich udev-Regeln verwenden, um Treiber bestimmten Schnittstellen auf dem USB-Gerät zuzuweisen? Wenn ich zum Beispiel wollte, dass das usbnet-Modul automatisch auf der Schnittstelle 0 anstelle von USB-Speicher verwendet wird, ist das in udev möglich?

Linsek
quelle
1
Wenn ein Teil des Problems darin besteht, das richtige Modul zu laden, lesen
Gilles 'SO - hören Sie auf, böse zu sein'
1
Benötigen Sie überhaupt das USB-Speichermodul? denn wenn nicht, kannst du es auf eine schwarze Liste setzen und es würde überhaupt nicht geladen.
Hanan N.
@ Gilles, ich kann das LKM erfolgreich laden. Meine Frage ist, wie ich das manuell und automatisch an das Gerät anhänge.
Linsek
@Hanan, momentan habe ich keine Verwendung für das USB-Speichermodul. Möglicherweise muss ich es auf eine schwarze Liste setzen, um das richtige Modul automatisch anzuschließen, aber zuerst muss ich wissen, wie man das USB-Netzwerk anschliesst.
Linsek
1
Das @ njozwiak-Modul usbnetwird nicht automatisch geladen, da es keine Informationen über die Hardware enthält, die es verwenden kann. Versuchen Sie, den richtigen Treiber zu finden und verwenden Sie zum Beispiel modinfo kalmia. In den aliasZeilen sehen Sie Hersteller-ID xxxx und Produkt-ID yyyy als usb:vxxxxpyyyy. Oder Sie können die Datei /lib/modules/kernel_version/modules.usbmap bearbeiten und für Ihre Hardware die Zeile löschen, in der sich das HW-Modul für den USB-Speicher befindet, oder den USB-Speicher mit dem richtigen Netzwerktreiber ändern. Aber nach depmod -adieser Änderung wird verschwinden ...
Jan Marek

Antworten:

20

Im ersten Teil der Frage habe ich nach einem USB-Treiber gesucht und konnte keinen besseren Weg finden, ihn zu entfernen, als das, was Sie bereits mit libusb machen.

Was den zweiten Teil der Frage betrifft, kann udev auf das Laden von Treibern reagieren , aber nicht die Zuweisung eines bestimmten Treibers zu einem Gerät erzwingen .

Jeder Treiber im Linux-Kernel ist für ein oder mehrere Geräte verantwortlich. Der Treiber selbst wählt die unterstützten Geräte aus. Dies geschieht programmgesteuert, dh durch Überprüfen des Anbieters und der Produkt-ID des Geräts oder, wenn diese nicht verfügbar sind (z. B. ein altes Gerät), durch Ausführen einiger Heuristiken zur automatischen Erkennung und Überprüfung der Integrität. Sobald der Treiber sicher ist, dass er ein unterstütztes Gerät gefunden hat, hängt er sich daran an. Kurz gesagt, Sie können einen bestimmten Treiber häufig nicht zwingen, ein bestimmtes Gerät zu verwenden. Manchmal ist ein Gerätetreiber jedoch großzügig mit dem, was er akzeptiert, und ein Gerät kann funktionieren, von dem er nichts weiß. Ihre Laufleistung wird variieren! In der Vergangenheit musste ich seltsame PCI-Geräte- / Anbieter-IDs manuell zu Treibern hinzufügen, die sie unterstützen sollten, mit gemischtem Erfolg und einigen amüsanten Kernel-Abstürzen.

Bei Modulen gibt es jetzt einen zusätzlichen Schritt. Die Modullader wird vom Kernel aufgeweckt , wenn ein neues Gerät erkannt wird. Es wird ein 'Modalias'-String übergeben, der das Gerät identifiziert und für USB-Geräte ungefähr so ​​aussieht:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

Diese Zeichenfolge enthält die Geräteklasse ( usb) und klassenspezifische Informationen (Hersteller / Gerät / Seriennummer, Geräteklasse usw.). Jeder Kerneltreiber enthält eine Zeile wie:

MODULE_ALIAS("usb:...")

Welche müssen mit den Usbalias übereinstimmen (Platzhalter werden verwendet, um mehrere Geräte abzugleichen). Wenn das modaliasvom Treiber unterstützte übereinstimmt, wird dieser Treiber geladen (oder über das neue Gerät benachrichtigt, falls es bereits vorhanden ist).

Sie können die unterstützten Geräte (nach Modalias) und die zugehörigen Module mit anzeigen

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

Wenn Sie nach dem USB-Speichergerätetreiber suchen, werden Sie feststellen, dass er bestimmte Geräte unterstützt, die vom Hersteller und der Geräte-ID unterstützt werden. Außerdem wird versucht, alle Geräte mit der richtigen (Speicher-) Klasse zu unterstützen, unabhängig vom Hersteller / Gerät .

Sie können dies mit Hilfe von Userspace-Mechanismen auf Ihrem Betriebssystem ( /etc/modprobe.d/unter Debian und Freunden) beeinflussen. Sie können Module auf die Blacklist setzen oder Module angeben, die von Modalias geladen werden sollen, genau wie die modules.aliasDatei (und die gleiche Syntax verwenden). depmod -ageneriert dann die Muster des Modulladers neu.

Sie können dieses Pferd zwar zum Wasser führen, aber nicht zum Trinken bringen. Wenn der Treiber Ihr Gerät nicht unterstützt, sollte er es ignorieren.

Dies ist die Theorie im allgemeinen Fall.

In der Praxis und im Fall von USB sieht es so aus, als ob Ihr Gerät über zwei Schnittstellen verfügt , von denen einer Speicher ist. Der Kernel wird auf die Speicher befestigen Schnittstelle der Gesamtvorrichtung. Wenn die andere Schnittstelle die richtige Klasse hat, der usbnetFahrer könnte daran binden. Ja, Sie können mehrere Treiber an dasselbe physische Gerät anschließen, da ein USB-Gerät mehrere Schnittstellen exportiert (z. B. meine Logitech G15-Tastatur exportiert zwei, weil sie ein Tastaturgerät und einen LCD-Bildschirm hat, die jeweils von einem separaten Treiber verwaltet werden). .

Die Tatsache, dass die zweite Schnittstelle Ihres USB-Geräts nicht erkannt wird, weist auf mangelnde Unterstützung im Kernel hin. In jedem Fall können Sie die Geräteschnittstellen / Endpunkte mit äußerst detailliert auflisten lsusb -v | lessund dann zu Ihrem bestimmten Gerät scrollen (Sie können die Ausgabe nach Gerät einschränken: Hersteller-ID oder USB-Pfad, wenn Sie dies wünschen).

Bitte beachten Sie: Ich vereinfache hier ein bisschen in Bezug auf die logische Struktur von USB-Geräten. Beschuldigen Sie das USB-Konsortium. :)

Alexios
quelle
4
static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);Gibt es schon im Code, ist es mit Modalias überflüssig?
Thomas
In meinem Fall werden diese Zeilen irgendwo im Treiber durch Makefile-Magie automatisch generiert. Deshalb habe ich dreimal die Zeilen für MODULE_ALIAS hinzugefügt, aber es wird nie aufgelistet. Trotzdem danke für das lsusb -v. damit konnte ich es überprüfen und den Fehler in meiner Idee finden. Ich habe dann die Quelle nach einem bekannten Bezeichner durchsucht und das Array mit den Einträgen gefunden, die ich bearbeiten musste.
JackGrinningCat