LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

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