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 libusb
biblioteki, 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?
usbnet
nie ł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ładmodinfo kalmia
. Walias
wierszach zobaczysz identyfikator dostawcy xxxx i identyfikator produktu yyyy asusb: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 podepmod -a
tej zmianie odejdzie ...Odpowiedzi:
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:
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:Które muszą pasować do usbali (symbole wieloznaczne są używane do dopasowania wielu urządzeń). Jeśli
modalias
pasuje 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
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 jakmodules.alias
plik (i przy użyciu tej samej składni).depmod -a
ponownie 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ę,
usbnet
sterownik 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. :)
źródło
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?