Jak przypisać sterownik USB do urządzenia

30

To pytanie jest dwojakie:

Po pierwsze, w jaki sposób ręcznie odłączyć sterownik od urządzenia USB i podłączyć inny? Na przykład mam urządzenie, które po podłączeniu automatycznie korzysta ze sterownika pamięci USB.

wyjście 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
        ...

Nie chcę używać sterownika pamięci USB, więc w mojej aplikacji korzystam z libusbbiblioteki, aby odłączyć sterownik pamięci USB, a następnie przejmuję interfejs. Następnie mogę wysyłać dane do iz aplikacji działających na moim urządzeniu USB i na moim systemie Linux.

Jak ręcznie odłączyć sterownik poza aplikacją?


Po drugie, jak automatycznie przypisać sterownik do dołączenia we wtyczce urządzenia? Obecnie mam konfigurację reguły udev do automatycznego ustawiania uprawnień urządzenia:

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

Czy mogę używać reguł udev do przypisywania sterowników do określonych interfejsów na urządzeniu USB? Na przykład, jeśli chcę, aby moduł usbnet był używany automatycznie w interfejsie 0 zamiast w usb-storage, czy jest to możliwe w udev?

linsek
źródło
1
Jeśli częścią problemu jest ładowanie odpowiedniego modułu, patrz Kamera internetowa w Angström
Gilles „SO - przestań być zły”,
1
Czy potrzebujesz modułu pamięci USB? bo jeśli nie, możesz umieścić go na czarnej liście i nie załaduje się wcale.
Hanan N.,
@Gilles, z powodzeniem mogę załadować LKM. Moje pytanie brzmi: jak ręcznie i automatycznie dołączyć to do urządzenia?
linsek
@ Hanan, obecnie nie mam zastosowania do modułu pamięci USB. Być może będę musiał umieścić go na czarnej liście, aby automatycznie dołączyć poprawny moduł, ale najpierw muszę wiedzieć, jak podłączyć moduł usbnet.
linsek
1
@njozwiak Moduł usbnetnie ładuje się automatycznie, ponieważ nie ma informacji o sprzęcie, który może z niego korzystać. Spróbuj znaleźć odpowiedni sterownik i użyj na przykład modinfo kalmia. W aliaswierszach zobaczysz identyfikator dostawcy xxxx i identyfikator produktu yyyy as usb:vxxxxpyyyy. Lub możesz edytować plik /lib/modules/kernel_version/modules.usbmap, a dla swojego HW możesz usunąć linię, gdzie jest dla ciebie moduł HW-pamięć usb lub zmienić usbstorage z odpowiednim sterownikiem sieci. Ale po depmod -atej zmianie odejdzie ...
Jan Marek

Odpowiedzi:

20

W pierwszej części pytania szukałem i nie mogłem znaleźć lepszego sposobu na odłączenie sterownika USB niż to, co już robisz z libusb.

Jeśli chodzi o drugą część pytania, udev może reagować na ładowanie sterownika, ale nie może wymuszać przypisania określonego sterownika do urządzenia.

Każdy sterownik w jądrze Linuksa jest odpowiedzialny za jedno lub więcej urządzeń. Sam sterownik wybiera obsługiwane urządzenia. Robi to programowo, tj. Sprawdzając dostawcę urządzenia i identyfikator produktu, lub, jeśli nie są one dostępne (np. Stare urządzenie), wykonując niektóre heurystyki z automatycznym wykrywaniem i sprawdzanie czystości. Gdy kierowca jest pewien, że znalazł urządzenie, które obsługuje, dołącza się do niego. Krótko mówiąc, często nie można zmusić konkretnego sterownika do korzystania z określonego urządzenia. Czasami jednak sterownik urządzenia jest hojny z tym, co akceptuje, a urządzenie może działać, o którym nie wie. Twój przebieg będzie się różnić! W przeszłości musiałem ręcznie dodawać dziwne identyfikatory urządzeń PCI / dostawców do sterowników, które powinny je obsługiwać, z mieszanym sukcesem i kilkoma zabawnymi awariami jądra.

Teraz w przypadku modułów jest dodatkowy krok. Ładowarka moduł jest budzony przez jądro po wykryciu nowego urządzenia. Przekazano ciąg „modalias”, który identyfikuje urządzenie i wygląda mniej więcej tak:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

Ciąg ten zawiera klasę urządzenia ( usb) i informacje specyficzne dla klasy (sprzedawca / urządzenie / numer seryjny, klasa urządzenia itp.). Każdy sterownik jądra zawiera linię taką jak:

MODULE_ALIAS("usb:...")

Które muszą pasować do usbali (symbole wieloznaczne są używane do dopasowania wielu urządzeń). Jeśli modaliaspasuje do obsługiwanego przez sterownik, sterownik jest ładowany (lub powiadamiany o nowym urządzeniu, jeśli już tam jest).

Możesz zobaczyć obsługiwane urządzenia (według wersji) i powiązane z nimi moduły

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

Jeśli poznasz sterownik urządzenia pamięci USB, zobaczysz, że ma on określone urządzenia obsługiwane przez producenta i identyfikator urządzenia, a także spróbuje obsługiwać dowolne urządzenie z odpowiednią klasą (pamięci), bez względu na dostawcę / urządzenie .

Możesz na to wpływać za pomocą mechanizmów przestrzeni użytkownika w systemie operacyjnym ( /etc/modprobe.d/w Debianie i znajomych). Możesz umieścić na czarnej liście moduły lub określić moduły, które będą ładowane przez moduły, podobnie jak modules.aliasplik (i przy użyciu tej samej składni). depmod -aponownie wygeneruje wzorce modułu ładującego.

Jednak nawet jeśli możesz doprowadzić tego konia do wody, nie możesz zmusić go do picia. Jeśli sterownik nie obsługuje Twojego urządzenia, powinien go zignorować.

Taka jest teoria w ogólnym przypadku.

W praktyce, w przypadku USB, wydaje się, że twoje urządzenie ma dwa interfejsy , z których jeden to pamięć. Jądro zostanie podłączone do interfejsu pamięci całego urządzenia. Jeśli drugi interfejs ma odpowiednią klasę, usbnetsterownik może się do niego podłączyć. Tak, możesz mieć wiele sterowników podłączonych do tego samego urządzenia fizycznego , ponieważ urządzenie USB eksportuje wiele interfejsów (np. Moja klawiatura Logitech G15 eksportuje dwa, ponieważ ma urządzenie klawiatury i ekran LCD, z których każdy obsługiwany jest przez osobny sterownik) .

Fakt, że drugi interfejs urządzenia USB nie został wykryty, wskazuje na brak wsparcia w jądrze. Niezależnie od przypadku, możesz wymienić interfejsy urządzenia / punkty końcowe w niesamowitej szczegółowości za pomocą lsusb -v | less, a następnie przewinąć w dół do konkretnego urządzenia (możesz ograniczyć dane wyjściowe według urządzenia: identyfikator dostawcy lub ścieżkę USB, jeśli masz taką skłonność).

Uwaga: nieco upraszczam tutaj nieco w odniesieniu do logicznej struktury urządzeń USB. Obwiniaj konsorcjum USB. :)

Alexios
źródło
4
Jest już static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);w kodzie, czy jest redundantny z modaliami?
Thomas
W moim przypadku linie te są generowane automatycznie przez magię Makefile w dowolnym miejscu w sterowniku. Dlatego dodałem trzykrotnie wiersze do MODULE_ALIAS, ale nigdy nie ma na liście. W każdym razie dzięki za lsusb -v. dzięki temu mogłem to sprawdzić i znaleźć wadę w moim pomyśle. Następnie grepuję źródło znanego identyfikatora i znalazłem tablicę z wpisami, którymi musiałem manipulować.
JackGrinningCat