[DLA PRAKTYKÓW] USB w systemie Linux
Więcej informacji o każdym z urządzeń:
$ lsusb -v Bus 001 Device 062: ID 045e:0745 Microsoft Corp. Nano Transceiver v1.0 for Bluetooth # Urządzenie USB: Device Descriptor: idVendor 0x045e Microsoft Corp. idProduct 0x0745 Nano Transceiver v1.0 for Bluetooth iSerial 0 # Ilość konfiguracji (1) bNumConfigurations 1 Configuration Descriptor: # Deklarowane zapotrzebowanie na prąd: MaxPower 100mA # Opisy interfejsów w ramach konfiguracji. Ich klasy i endpointy: Interface Descriptor: bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceProtocol 1 Keyboard Endpoint Descriptor: bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 4 Interface Descriptor: bInterfaceClass 3 Human Interface Device bInterfaceProtocol 2 Mouse Endpoint Descriptor: bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x000a 1x 10 bytes bInterval 1 Interface Descriptor: #kolejny interfejs Device Status: 0x0000 (Bus Powered)
W przypadku myszki USB (bezprzewodowej). Odbiornik rejestruje zarówno urządzenie myszy, jak i klawiatury. Prawdopodobnie w bezprzewodowych klawiaturach, producent wykorzystuje ten sam fimrware.
Każdy z trzech zdefiniowanych w urządzeniu interfejsów, reprezentowany jest przez oddzielny wpis w sysfs:
- 1-1.3:1.0 – konfiguracja 1, interfejs 0
- 1-1.3:1.1 – konfiguracja 1, interfejs 1 (mysz)
- 1-1.3:1.2 – konfiguracja 1, interfejs 2
Komunikacja z interfejsem realizowana jest przez sterownik usbhid:
$ ls -l /sys/bus/usb/devices/1-1.3:1.1/ driver -> ../../../../../../../bus/usb/drivers/usbhid
Analogicznie – w katalogu sterownika, znajdują się dowiązania symboliczne do wszystkich skojarzonych z nim urządzeń.
USB Monitor
Monitor USB pozwala analizować transfery przy pomocy biblioteki libpcap i narzędzi z niej korzystających.
Jeżeli nie został on wkompilowany na stałe, należy załadować moduł:
modprobe usbmon
Narzędzia: wireshark i tcpdump widzą dodatkowe interfejsy usbmonX. Każdy z nich odpowiada jednej z dostępnych w systemie magistral i pozwala podsłuchiwać dane nią przesyłane.
Mysz USB (podłączona, jak w listingu powyżej – do pierwszej magistrali). Analiza ruchu interfejsu usbmon1 pokazuje, że komunikacja odbywa się przez cyklicznie próbkowany endpoint typu interrupt.
USB Gadget
Oprócz kontrolerów pracujących w trybie hosta, Linux obsługuje także te, działające w trybie urządzenia (USB Device Controller – UDC). Urządzenie Embedded Linux może pracować jako klient USB.
Ta część podsystemu USB nazywa się USB Gadget. Sterowniki znajdują się w https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/gadget?id=v4.0
Kontrolery UDC (w przeciwieństwie do host-ów) nie są ustandaryzowane. Każdy z nich wymaga dedykowanego sterownika.
Kontroler udostępnia endpointy. Na nich budowane są interfejsy, konfiguracje i urządzenie. Podczas konfiguracji kodu źródłowego jądram, można wybrać wiele sterowników urządzeń klienckich kompilowanych jako moduły, albo jeden wkompilowany na stałe w jądro.
Niektóre zestawy deweloperskie – na przykład popularne Raspberry Pi – posiadają wprawdzie złącze USB, jednak służy ono tylko do zasilania – linie danych nie są podłączone do procesora.
Podsystem rozwijany jest od 2003 roku. Początkowo dostępne w nim były tylko sterowniki realizujące funkcje kilku typowych urządzeń. Na przykład: g_ether.
W Wandboard Solo, załadowanie modułu:
$ modprobe g_ether host_addr=ca:3c:a3:4f:02:01
Spowoduje, że w systemie pojawi się interfejs usb0. Po podłączeniu kabla USB do hosta – wykrywa on i konfiguruje interfejs sieciowy usb0 (na przykład). Pomiędzy tymi dwoma interfejsami, można przesyłać pakiety Ethernetowe.
Adresy MAC są generowane losowo przy każdym załadowaniu modułu. Parametr: host_addr wymusi użycie podanego adresu po stronie hosta. Ułatwi to konfigurację połączeń w narzędziach takich, jak Network Manager.
$ dmesg | tail usb 1-1.1: new high-speed USB device number 64 using xhci_hcd usb 1-1.1: New USB device found, idVendor=0525, idProduct=a4a2 usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-1.1: Product: RNDIS/Ethernet Gadget usb 1-1.1: Manufacturer: Linux 4.0.0 with 2184000.usb cdc_ether 1-1.1:1.0 usb0: register 'cdc_ether' at usb-0000:00:10.0-1.1, CDC Ethernet Device, ca:3c:a3:4f:02:01
Identyfikatory: producenta i urządzenia zostały użyczone przez firmę Netchip – należy zmienić je na własne w przypadku używania powyższego sterownika w produkcie komercyjnym.
$ lsusb Bus 001 Device 064: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget
Z czasem Framework USB Gadget rozbudowano o kolejne funkcje:
- gadgetfs – umożliwiający tworzenie sterowników urządzeń-klientów w przestrzeni użytkownika,
- composite framework – do urządzeń wielofunkcyjnych (Etherner + Serial). Istniejące sterowniki pojedynczych urządzeń były stopniowo przenoszone do tego frameworku,
- funkcje USB gadget w configfs – włączone w wersji 3.11 wraz z modyfikacjami w 3.13.
configfs – to uniwersalny wirtualny system plików, który pozwala udostępniać w przestrzeni użytkownika obiekty jądra. Po włączeniu funkcji configfs w USB gadget, można wygodnie rekonfigurować urządzenia i ich funkcje.
$ mount -t configfs config /sys/kernel/config $ cd /sys/kernel/config $ cd usb_gadget
Katalog jest generowany tylko, jeżeli w konfiguracji jądra włączono właściwe funkcje.