11/30/2014

Linux USB Host URB 분석

1. USB Host에서 URB Monitor

USB URB Debugging하기 위해서는 Host 에서 URB를 Capture 동작이 되며, 반드시 HCD와 함께 같이 동작해야한다. 



1.1 USB Kernel Message 및 Device Descriptor 분석 

  • Kernel Message 확인  
USB Request Blocks (URBs) 보다는 USB Descriptor 를 분석하고 관련 USB Driver의 debug message들을 분석하여 기본동작을 확인하자 

$ cat /proc/kmsg
$ dmeg 

  • USB Device Descriptor 분석 과 Kernel Message 분석법  
우선적으로 USB Hots에서 각 Device 의 Descriptor를 우선적으로 분석해야한다.
  https://ahyuo79.blogspot.com/2017/10/linux-usb-1.html


1.2 USB Host 의 usbmon 동작구조 이해  

아래의 TI문서를 읽어보면 아래와 같이 usbmon이라는 HCD와 연결되어 동작되어 debugging할수 있게 되어있다.


USB Host에서 Kernel 의 usbmon  세부사용법
  http://elinux.org/images/1/17/USB_Debugging_and_Profiling_Techniques.pdf
  https://drive.google.com/open?id=0B_ehveuLi8MVZ3lHYU11QVViUEk


  • HCD 와 usbmon 같이 동작되는 구조 
USB Host Mode에서 usbmon 과 동작할 경우 
  1. Binary File은 /dev/usbmonx 로 생성되어 확인가능
  2. Text 정보는 /sys/kernel/debug 로 확인 가능 (Kernel Config에서 별도 설정)

  • URB Binary 분석방법-A (좌측) 
/dev/usbmonx를 tcpdump를 이용하여 dump를 하고, 이를  wireshark로 분석하는 것이다.


  • URB Text 분석방법-B (우측)
/sys/kernel/debug/usb/usbmon/Xu를 이용하여 vusb-anlayzer라는 linux에서 돌아가는 프로그램을 이용하는 것이다.


1.3 Kernel 설정 변경 

  • Kernel Config 설정 
# usbmon 기능 과 Kernel Debug 기능 on 
....
CONFIG_USB_MON=m
...
CONFIG_DEBUG_FS=y
...

  • USB Host의 EHCI의 IRQ 에서 URQ 전송 
ehci_irq () 주요 파일 urq로 core로 DMA로 전송 status 로 HW 정보들을 알수 있다.
ehci_irq () 주요 파일 urq로 core로 DMA로 전송 status 로 HW 정보들을 알수 있다.
#define  STS_ASS  (1<<15 ...="" access="" advance="" also="" any="" are="" as="" async="" bits="" change="" completion="" define="" detect="" error="" errors="" flags="" frame="" interrupted="" intr_enable="" list="" normal="" not="" on="" over="" overflow="" pci="" periodic="" port="" pre="" reason="" reclamation="" reserved="" rolled="" running="" schedule="" short="" some="" status="" sts_="" sts_err="" sts_fatal="" sts_flr="" sts_halt="" sts_iaa="" sts_int="" sts_pcd="" sts_pss="" sts_recl="" such="" these="">



2. Linux에서 usbmon 기반으로 wireshark 분석 

Window와 Linux의 각 Driver를 보면 아래와 같다.
  • Window : USBPcap  ( Wireshark에서 기본제공)
  • Linux     : usbmon (/dev/usbmonx , Kernel에서 제공해야함)

Linux에서 USB의 기본적인 Descriptor들은 아래의 명령으로 쉽게 확인가능

$ cat /sys/kernel/debug/usb/devices  
or 
$ lsusb 

하지만, URB를 모니터를 하기위해서는 Linux Kernel에서 CONFIG_USB_MON 설정필요하며,  Linux Kernel에서 설정이되면 /dev/usbmonX 생성이 되며
이를 기반으로 USB의 URB 모니터 즉 Capture가 가능하다

Kernel Config usbmon 
  https://www.kernel.org/doc/Documentation/usb/usbmon.txt


  • USB URB Capture 방법 
$ mount -t debugfs none_debugs /sys/kernel/debug  // mount가 기본으로 거의되어있음
$ modprobe usbmon  // module로 했을 경우 

$ ls /sys/kernel/debug/usb/usbmon
 0s  0u  1s  1t  1u  2s  2t  2u  3s  3t  3u  4s  4t  4u

$ cat /sys/kernel/debug/usb/usbmon/0u > /tmp/1.mon.out // 모든 USB Bus Capture

$ cat /sys/kernel/debug/usb/usbmon/3u > /tmp/1.mon.out  // URB를 Capture 추정 추후 Wireshark와 연동을 해봐야 알것같음 

USB Host 에서 usbmon 이용하여 tcpdump로 capture하는법 
  https://ahyuo79.blogspot.com/2014/11/usb-host-gadget-debug-2.html

Linux에서 USB Capture를 위한 Setup 방법
  https://wiki.wireshark.org/CaptureSetup/USB

Linux에서 Bluetooth Capture를 위한 Setup 방법
  https://wiki.wireshark.org/CaptureSetup/Bluetooth

  • HOST OS 별로 USB 지원을 확인가능 
아직 USB의 RNDIS를 이용하여 사용하는 기능은 확인을 해보지 못했다.
글을 읽다보면, 기본 OS를 Linux로 사용하고, Virtual로 Window를 설치한 다음 이용하는 기능같다.

  https://wiki.wireshark.org/CaptureSetup/NetworkMedia
  http://desowin.org/usbpcap/capture_limitations.html

11/26/2014

USB Driver의 기본구조 및 Linux 관련 Driver

1. USB의 Pin과 종류 

  • USB의 Pin Type 
USB Type A 와 B로 나누어지며,  기본 USB 1.0은 4 Pin이 기본이며, 이 후 OTG가 지원이 되면서,
Micro USB A/B 부터 5Pin으로 변경되어 ID Pin을 필요


  • USB의 기본 4 Pinout
Type-A and -B pinout
PinNameWire color[a]Description
1VBUSRed orOrange+5 V
2D−White orGoldData−
3D+GreenData+
4GNDBlack orBlueGround


  • USB 의 5 Pinout (OTG이후)
Mini/Micro-A and -B pinout
PinNameWire color[a]Description
1VBUSRed+5 V
2D−WhiteData−
3D+GreenData+
4IDNo wireOn-The-Go ID distinguishes cable ends:
  • "A" plug (host): connected to GND
  • "B" plug (device): not connected
5GNDBlackSignal ground


USB는 일반 USB Pin을 제외하고 5 Pin이며, 이때 새로 생긴 것이 OTG (On-The-Go)  Pin이다.
이는 HOST가 될수 있으며, Device가 될수도 있기때문에 이 Pin은 중요한다.


  • 자세한 내용은 Wiki 참조
  https://en.wikipedia.org/wiki/USB
  http://processors.wiki.ti.com/index.php/DM81xx_AM38XX_USB_User_Guide


2. USB Host Driver의 구조 

USB는 아래와 같이 USB Version에 따라 지원되는 기능이 달라지며 자세한 내용은 아래의 링크를 참조하자.

  • USB Host Controller 기본구조 
  1. OHCI (Open Host Controller Interface) 
    1. 처음 만들어진 USB 1.0 / 1.1 표준 USB Host Controller 이며, fireworks device를 위해 사용되어진다고하는데, 최근 Linux Kernel에 존재함 
  2. UHCI(Universal Host Controller Interface)
    1.  USB 1.x 부터 인텔에 의해 만들어져서 로얄티가 있다고 하며, 아직도 Linux에 소스가 존재함

OHCI 와 UHCI 관련내용

  • USB Host Controller 확장구조 ( USB2.0 / USB3.0)
  1. EHCI (Enhanced Host Controller Interface)
    1. USB 2.0 지원을 위한 표준이며 보통 Linux Kernel에 존재한다.  
  2. xHCI (Extensible Host Controller Interface)
    1. USB 3.0 지원을 한다고 하며, OHCI/UHCI/EHCI를 대체를 한다고 아직 사용을 못해봤다. 

Chip Maker마다 다르겠지만, 기본 자사 USB Host Controller Driver(OHCI)EHCI를 조합으로 사용을 하는 것으로 보이며, 
각 Chip Maker의 USB Host Controller가 OHCI or UCHI를 선택해서 사용하는 것 같은데, 로얄티 문제로 주로 OHCI기반으로 구성하는 것 같다.  




USB Device 의 Class Descriptor 와 USB Class Driver 와 연결
  https://ahyuo79.blogspot.com/2014/11/class-descriptor.html


  • USB CDC for LTE 관련 Driver 
  https://wiki.openwrt.org/doc/recipes/3gdongle
  http://tpholic.com/xe/?mid=ibmqna&page=2&document_srl=6593791
  https://www.linuxquestions.org/questions/linux-newbie-8/how-do-i-define-ttyusb0-423976/
  https://www.olimex.com/forum/index.php?topic=558.0
  http://www.makelinux.net/ldd3/chp-13-sect-4
USB File System 의 이용
  http://www.hep.by/gnu/kernel/usb/usbfs.html
  https://stackoverflow.com/questions/25793399/mount-usbfs-on-linux-3-10-kernel


2.1 USB Host Module 동작 

아래와 같이 USB는 Interface Descriptor와 Probe가 가장 중요하므로, 아래와 같이 각 기능을 확인을 해보자.

요즘은 USB Driver를 모듈 만들어 modprobe를 이용하여 vendor, product 정보를 넣고 올린다. (udevd 이용)

USB의 Host의 USB Device Module기본동작은 다음과 같다
  1. Device/Interface Descriptor를 분석하여 맞게 Driver Loading 
  2. Interface driver는 보통 Probe에서 다른 Interface driver로 연결
  3. Endpoint Descriptor를 분석하여 URB를 Host와 Device가 통신할 것인지 분석. 
최종의 Driver는 Endpoint Descriptor 기준으로 URB
URB는 USB Request Block으로 Endpoint Descriptor의 기초로 만들어지면, 이 DATA 구조로 Host와 Device는 통신을 하게된다.


  • Probe의 역할
Probe는 가장 중요한 역할을 하며, 각각의 Interface를 분석하며, 다른 Driver를 호출한다.
물론 최종 Interface Driver가 존재하며, 이곳에서 Endpoint Descriptor와 URB관련 부분이 존재한다.


2.2 USB Host의 Core File의 기능 

  • USB HCD Core Files
Linux Version 마다 다르겠지만, drivers/usb/core 위치한 driver들이 각 명령을 Control 하고 제어를 담당한다 
  1. USB의 기본적인 Control ( GET_DESCRIPTOR ...)
  2. USB의 URB 전송 및 제어 
  3. Hub Class 
  4. 다른 USB Driver Probe 제어 (Device/Interface Descriptor 기준)
  http://elixir.free-electrons.com/linux/v2.6.28.1/source/drivers/usb/core/hcd.c#L428
  http://elixir.free-electrons.com/linux/v2.6.28/source/drivers/usb/core/usb.c#L606


  • USB Device Driver 등록 (Module의 관리)
  1. usb_register_driver는 모든 USB Driver가 등록하고 이를 관리. (Linked List)
  2. usb_register_driver 내에는 usb_probe_interface 가지고 있으며,module내의 probe별도 
  3. usb_probe_interface는 USB match 관련부분 등록된 USB Driver를 호출 전 관리 
  http://elixir.free-electrons.com/linux/v2.6.28/source/drivers/usb/core/driver.c


  • 간혹 open() 에서 사용되는 usb_find_interface로 Interface driver를 찾음
  http://elixir.free-electrons.com/linux/v2.6.28/source/drivers/usb/core/usb.c#L163


2.3 USB Host Module 기본구조

module_init/module_exit 할때 각각의 module을 usb_register_driver 등록 및 해제한다.


  • 기본 USB Module 
  http://elixir.free-electrons.com/linux/v3.13-rc1/source/drivers/usb/usb-skeleton.c


2.4 USB Host 연결된 Module Example 

아래의 Driver를 Probe를 간단히 분석해보면, probe에서 다시 usbnet_probe를 호출하여 결국 usbnet_probe를 사용하여

Endpoint가 결정되고, URB 부분이 완성된다.

  http://elixir.free-electrons.com/linux/v3.13-rc1/source/drivers/net/usb/qmi_wwan.c#L794
  http://elixir.free-electrons.com/linux/v3.13-rc1/source/drivers/net/usb/usbnet.c#L1543

  • 관련 Linux Driver 문서 
  http://www.makelinux.net/ldd3/chp-13-sect-4


USB_DEVICE (Venid, ProductID)
struct usb_device_id
usb_register(&pen_driver);
device_register (&port->dev);



  • Debug는 USB Host에서 Probe시 Interface의 정보기술


 xxxx_probe(struct usb_interface *intf, const struct usb_device_id *prod)
{
 printk("intf No:%d Ty:%d Cl:%d SC:%d Pr:%d\n"
   ,intf->cur_altsetting->desc.bInterfaceNumber
   ,intf->cur_altsetting->desc.bDescriptorType
   ,intf->cur_altsetting->desc.bInterfaceClass
   ,intf->cur_altsetting->desc.bInterfaceSubClass
   ,intf->cur_altsetting->desc.bInterfaceProtocol
 ); //jhlee

}



  • inlclude/linux/usb.h

struct usb_interface {
 /* array of alternate settings for this interface,
  * stored in no particular order */
 struct usb_host_interface *altsetting;

 struct usb_host_interface *cur_altsetting; /* the currently
      * active alternate setting */
 unsigned num_altsetting; /* number of alternate settings */

 int minor;   /* minor number this interface is
      * bound to */
 enum usb_interface_condition condition;  /* state of binding */
 struct device dev;  /* interface specific device info */
 struct class_device *class_dev;
};
...
struct usb_host_interface {
 struct usb_interface_descriptor desc;

 /* array of desc.bNumEndpoint endpoints associated with this
  * interface setting.  these will be in no particular order.
  */
 struct usb_host_endpoint *endpoint;

 char *string;  /* iInterface string, if present */
 unsigned char *extra;   /* Extra descriptors */
 int extralen;
};


  • inlclude/linux/usb_ch9.h

/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
 __u8  bLength;
 __u8  bDescriptorType;

 __u8  bInterfaceNumber;
 __u8  bAlternateSetting;
 __u8  bNumEndpoints;
 __u8  bInterfaceClass;
 __u8  bInterfaceSubClass;
 __u8  bInterfaceProtocol;
 __u8  iInterface;
} __attribute__ ((packed));


  http://elixir.free-electrons.com/linux/v4.3.3/source/include/uapi/linux/usb/cdc.h#L17
  http://elixir.free-electrons.com/linux/v3.17.5/source/drivers/net/usb/qmi_wwan.c#L845


3. USB OTG의 Gadget (Device) 구조 

USB Device의 구조는 설명했듯이 기본적인 USB에서 제공하는 각 Descriptor를 제공을해줘야한다.
그리고 이의 설정에 맟추어 EndPoint 와 URB로 USB HOST와 통신이 가능하도록 해줘야한다.

기존에는 별도의 USB Device Chip을 사용하는 경우도 있으나, 현재 Linux에서는 OTG기반으로 USB Gadget(Device)를 사용가능하다 


USB Gadget의 Function ACM
  http://elixir.free-electrons.com/linux/v3.7.9/source/drivers/usb/gadget/f_acm.c


3.1 USB Gadget Driver  

OTG(On-The-Go) Mode로  사용할 경우, USB는 Device Mode와 Host Mode가 동시 동작이 가능하기 때문에,
Host 이외에 Linux에서는 Gadget이라는 것을 이용하여 USB Device Mode를 지원한다.

아래와 같이 USB Device Mode로 사용할 경우 각 Class Device를 대충 알아보자.
대표적인 것들이 Mass Storage , CDC 등 다양하게 이용이되며, Module 형태로 Kernel에서 기본적으로 제공을 해준다.

반드시 Kernel Version을 확인하자.
  https://www.kernel.org/doc/htmldocs/gadget/index.html

  • 각 개별 모듈의 위치 
      drivers/usb/gadget

  • 주요소스 분석 부분 
  1. Gadget Driver에서의  Descriptor의 정의 및 설정부분 
  2. Endpoint를 어떻게 기본 통신을 하는지 개념 
  3. 이 Endpoint 통신부분과 다른 Interface와 어떻게 연결되는지 관련부분 Driver들   

  • 관련내용 
  http://www.linux-usb.org/gadget/
  http://www.linux-usb.org/gadget/h2-otg.html
  http://www.usb.org/developers/docs/
  https://events.linuxfoundation.org/sites/events/files/slides/LinuxConNA2013-andrzej.pietrasiewicz-usb-gadget-configfs_0.pdf

  • 관련소스
  https://elixir.free-electrons.com/linux/v3.3/source/drivers/usb/gadget
  https://elixir.free-electrons.com/linux/v2.6.29.3/source/drivers/usb/gadget
  https://git.linuxtv.org/pinchartl/uvcvideo.git/tree/drivers/usb/gadget?h=uvcvideo-gadget


  • TI-Sitara Version 예제 
기본동작 방식은 module 형태로 동작하기 때문에, 아래와 같이 lsmod로 자신의 module점검을 해보자.

# lsmod
Module                  Size  Used by
sd_mod                 28383  2
usb_storage            47815  1
scsi_mod              135887  2 usb_storage,sd_mod
bc_example              7250  0
sha512_generic          9903  0
sha512_arm             12079  0
drbg                   13425  1
des_generic            17736  0
cbc                     2324  0
xfrm_user              22606  2
xfrm4_tunnel            2040  0
ipcomp                  2257  0
xfrm_ipcomp             4311  1 ipcomp
esp4                    6466  0
ah4                     5627  0
bluetooth             327425  2
af_key                 26406  0
xfrm_algo               6970  5 ah4,esp4,af_key,xfrm_user,xfrm_ipcomp
usb_f_acm               5404  1
u_serial               11555  3 usb_f_acm
usb_f_ecm               6620  1
g_multi                 6330  0
usb_f_mass_storage     37916  2 g_multi
usb_f_rndis            15406  2 g_multi
u_ether                13577  3 usb_f_ecm,usb_f_rndis,g_multi
libcomposite           44392  5 usb_f_acm,usb_f_ecm,usb_f_rndis,g_multi,usb_f_mass_storage
configfs               26917  6 usb_f_acm,usb_f_ecm,usb_f_rndis,libcomposite,usb_f_mass_storage
rpmsg_pru               4958  0
virtio_rpmsg_bus       12724  1 rpmsg_pru
musb_dsps               8235  0
musb_hdrc              71486  1 musb_dsps
udc_core               12063  2 musb_hdrc,libcomposite
usbcore               195911  2 musb_hdrc,usb_storage
pm33xx                  5577  0
snd_soc_simple_card     7712  0
ecb                     1909  0
pru_rproc              11796  2
pruss_intc              7163  3 pru_rproc
ti_emif_sram            6242  1 pm33xx
wkup_m3_ipc             8278  1 pm33xx
sha256_generic          9503  1
hmac                    2735  1
wkup_m3_rproc           3669  1
md5                     1897  0
pvrsrvkm              406903  5 bc_example
sha1_generic            2621  0
sha1_arm_neon           6261  0
sha1_arm                3862  1 sha1_arm_neon
omap_aes_driver        19488  0
pruss                  10892  1 pru_rproc
remoteproc             26901  4 pruss,wkup_m3_rproc,pru_rproc,wkup_m3_ipc
omap_sham              21513  0
virtio                  7742  2 remoteproc,virtio_rpmsg_bus
virtio_ring            12163  2 remoteproc,virtio_rpmsg_bus
wlcore_sdio             6771  0
omap_rng                4759  0
rng_core                7794  1 omap_rng
snd_soc_tlv320aic3x    48260  1
musb_am335x             1426  0
ti_am335x_tsc           6029  0
rtc_omap                8272  1
omap_wdt                4634  0
ti_am335x_tscadc        6290  1 ti_am335x_tsc
sch_fq_codel            8289  4
cryptodev              38007  2

USB Gadget u_serial는 USB ACM으로  usb_f_acm과 연결되어 동작 (USB to Serial)


11/24/2014

Linux USB Descriptor 분석방법-2

1. USB Host에서 USB 기본정보 파악

Linux Device에서 아래의 lsusb 명령어를 이용하여 USB Host의 기본정보를 파악해보자

  • USB Host에서 Device 확인 

# lsusb
Bus 002 Device 003: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 
Bus 002 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 


  • USB Host에서 연결된 Device Layers 확인

# lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 2: Dev 3, If 0, Class=Mass Storage, Driver=usb-storage, 480M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M



1.1 USB Host에서 Descriptor 분석 

  • MassStorage 의 예제 

#lsusb -v

Bus 002 Device 003: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x090c Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.)
  idProduct          0x1000 
  bcdDevice           11.00
  iManufacturer           1 Samsung
  iProduct                2 Flash Drive DUO
  iSerial                 3 0320815120014277
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              300mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Binary Object Store Descriptor:
  bLength                 5
  bDescriptorType        15
  wTotalLength           22
  bNumDeviceCaps          2
  USB 2.0 Extension Device Capability:
    bLength                 7
    bDescriptorType        16
    bDevCapabilityType      2
    bmAttributes   0x00000006
      BESL Link Power Management (LPM) Supported
  SuperSpeed USB Device Capability:
    bLength                10
    bDescriptorType        16
    bDevCapabilityType      3
    bmAttributes         0x00
    wSpeedsSupported   0x000c
      Device can operate at High Speed (480Mbps)
      Device can operate at SuperSpeed (5Gbps)
    bFunctionalitySupport   2
      Lowest fully-functional device speed is High Speed (480Mbps)
    bU1DevExitLat           4 micro seconds
    bU2DevExitLat           4 micro seconds
.....


- 분석
Mass Storage의 경우 Interface Descriptor의 Class 만 설정을 했다.
물론 Vendor ID와 Product ID도 필수로 존재한다.


  • USB Hub 와 HID 예제 


#lsusb -v
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0002 2.0 root hub
  bcdDevice            4.04
  iManufacturer           3 
  iProduct                2 
  iSerial                 1 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval              12

Bus 002 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x80ee VirtualBox
  idProduct          0x0021 USB Tablet
  bcdDevice            1.00
  iManufacturer           1 
  iProduct                3 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      85
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10

Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0001 1.1 root hub
  bcdDevice            4.04
  iManufacturer           3 
  iProduct                2 
  iSerial                 1 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval             255


-분석
HID의 경우 Interface만 Class를 설정하지만,
HUB의 경우 Device와  Interface를 동시에 설정한다.



  • Device/Interface 의 Class 부분 체크 
  http://www.usb.org/developers/defined_class

  • lsusb 명령어
  http://linux.die.net/man/8/lsusb

  • lsusb porting
  https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=185091
  http://www.beyondlogic.org/usbnutshell/usb5.shtml

11/23/2014

Linux USB Descriptor 분석방법-1

1.  Linux 에서 분석설정  

linux에서 분석하는 방법은 가장 기본적으로 사용하는 것

  1. proc 정보 
  2. kernel log 


1.1  proc 정보 (usb filesystem )

proc는 기본적으로 아래와 같이 usbfs 을 사용해야 아래와 같이 지원이 가능하다.
mount -t usbfs none /proc/bus/usb
물론 Kernel에서 USB Filesystem을 사용해야한다.

# vi /etc/fstab
none  /proc/bus/usb  usbfs  defaults  0  0


# cat /proc/bus/usb/devices  or 
# cat /sys/kernel/debug/usb/devices

   상위분석방법 및 설정
   https://www.kernel.org/doc/Documentation/usb/proc_usb_info.txt

1.2 Kernel Log


# dmesg  // Kernel log 
# cat /proc/kmsg 


1.3 lsusb tool 사용 

linux에서 제공하는 lsusb tool을 사용하는 것이다.

2. Linux의 Proc의 정보분석 

현재 Device Descriptor 와 Driver의 정보확인이 가능하며, 연결상태를 확인하는 좋은 정보이다.
이 정보만으로는 연결상태를 알수는 있지만, debugging을 한다면, 역시 Kernel message가 필요하다.

2.1 USB Host 확인예제 

아래와 같이 기본  hub정보가 나온다.

# cat /proc/bus/usb/devices  or 
# cat /sys/kernel/debug/usb/devices

T:  Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 1
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 4.04
S:  Manufacturer=Linux 4.4.32-gadde2ca9f8 musb-hcd
S:  Product=MUSB HDRC host driver
S:  SerialNumber=musb-hdrc.2.auto
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 1
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 4.04
S:  Manufacturer=Linux 4.4.32-gadde2ca9f8 musb-hcd
S:  Product=MUSB HDRC host driver
S:  SerialNumber=musb-hdrc.1.auto
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

sys filesystem을 사용한다면, 아래에 위치에 존재할 것이다.

# /sys/bus/usb/devices/usb* 



  • 상위내용 분석 

D: 와 P:  모두 Device Descriptor에서 가져오는정보이며, 각각의 중요 정보들을 분석해보자.

D: Cls=: Class / Sub=: Sub Class / Prot=: Protocol 을 나타낸다.
P: Vendor ID와 ProductID가 확인가능하다.
I: 의 경우는 Interface descriptor로 Driver의 연결과 상관 이 있으므로 중요하다. 

  1. if#=x :    bInterfaceNumber
  2. Alt=0 :    bAlternateSetting
  3. EPs=1 :   bNumEndpoints
  4. Cls=09:   bInterfaceClass
  5. Sub=00:  bInterfaceSubClass
  6. Prot=00:  bInterfaceProtocol
  7. Driver=hub : linux에 연결된 Driver


  https://linux.die.net/man/1/usb-devices

  • 의미 설명 및 분석 

T = Topology (etc.)
B = Bandwidth (applies only to USB host controllers, which are
    virtualized as root hubs)
D = Device descriptor info.
P = Product ID info. (from Device descriptor, but they won't fit
    together on one line)
S = String descriptors.
C = Configuration descriptor info. (* = active configuration)
I = Interface descriptor info.
E = Endpoint descriptor info.


자세한 내용은 아래의 문서를 반드시 참조하자
  https://www.kernel.org/doc/Documentation/usb/proc_usb_info.txt


2.2 USB Hub에서 확인예제2 

이것은 최근에 작성한 것이며, 특이한 것은 Vendor Specific으로 작성했기때문에
아래와 같이 넣었다.


T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480 MxCh= 1
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0000 ProdID=0000 Rev= 2.06
S:  Manufacturer=Linux 2.6.18_IPNC_TENC-3003_1.0.1 musb-hcd
S:  Product=MUSB HDRC host driver
S:  SerialNumber=musb_hdrc
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=256ms

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=05c6 ProdID=9025 Rev= 2.32
S:  Manufacturer=Android
S:  Product=Android
S:  SerialNumber=0123456789ABCDEF
C:* #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=86(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E:  Ad=88(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=125us


대충 분석해보면, 2번째 T: 부터 봐야한다.
D: 의 Class/SubClass/Protocol은 사용되지 않는다. (추후 Interface에서 사용)
총 6개의 Interface로 구성이 되고, 0~4까지는 Vendor Specific Driver이다.
5번은 Class에서 Mass Storage로 연결이 되어 Driver에 연결 

11/09/2014

Window USB 분석방법 (Device Descriptor)

1. Window 에서 분석 방법 

다양한 Descriptor 분석 및 패킷분석 Tool이 존재하며, 아직 다 사용해보지 못해
각각의 장단점을 모르겠다.
현재 Wireshark까지 지원하다고 하니, Widnow는 너무 다양하다.

  • Wireshark 
  Network만 지원이 되었지만, USB 분석도 지원이 가능하다.
  https://www.wireshark.org/download.html

  • Thesycon USB Descriptor Dumper
  USB 분석을할때 사용을 해봐야 알겠지만,  사이트에서 제공하는 것으로 봐서 유용하겠다.
  http://www.thesycon.de/eng/usb_descriptordumper.shtml

  • Libusb Program (Descriptor 분석)
  Linux의 Libusb와 비슷한 기능을 가진 것 같으며, 상당히 유용할 것 같다. 
  현재 Window에서 사용할 일이 없기에 Link만 

  http://blog.tcltk.co.kr/?p=888
  http://wiki.tcltk.co.kr/wiki.php/libusb
  https://sourceforge.net/p/libusb-win32/wiki/Home/

  • USB Sniffer For Window 
  정확하게 Descriptor 는 분석이 되는지는 모르겠으나, 
  Packet Sniffer 용도로 사용 되는 것 같다.
  https://sourceforge.net/projects/usbsnoop/


2.2 Window 에서 Driver 지원 및 설정파일 확인 

Window를 USB Host를 사용하는 경우 대표적인 USB Device의 Class Driver는 지원을 해준다.
그리고, 관련 Class Driver의 설정파일, 즉 (*.sys) 을 알아두자.
만약, 별도의 설치 Driver가 필요할 경우도 발생한다.

  https://msdn.microsoft.com/en-us/library/windows/hardware/ff538820(v=vs.85).aspx


11/02/2014

Device/Interface Descriptor 의 Class 와 Device Driver

1. Device/Interface Descriptor의 Class 

Device/Interface Descriptor는 Driver의 Loading과 밀접한 관계있으며,상위 두 Descriptors들은 아래 값에 따라 Class가 구분이 되어 Driver와 연관되어 동작된다.
경우에따라 본인이 Class를 제외하고 직접 정의를 하여서 구현을 해도 좋다.
  1. Class 
  2. SubClass 
  3. Protocol

  • USB Class Code 표 (반드시 확인) 
  http://www.usb.org/developers/defined_class

  • USB Device Class Documents
  http://www.usb.org/developers/docs/devclass_docs/


1.1 특별한 Class 

Class와 Subclass는 각 Driver를 연결할때 중요하지만 아래와 같은 경우 특별하다.

  • Base Class FEh (Application Specific)
      상위 표 참고
  • Base Class FFh (Vendor Specific)

이는 Vendor ID와 Product ID가 중요하며, 이에 따라 각 Driver가 연결이 된다.
각 Class는 어떻게 정의할 지는 본인이 정하자.


2. Class 와 Driver 

상위 USB Device Class에 정의가 되어있다고, 각 OS가 모든 Driver를 제공을 해주는 것은 아니다.
그러므로, 각각의 Class 별로 확인을 해야한다. 물론 가장 많이 사용되는 Driver들은 OS가 거의 모두 지원을 해준다.
하지만, 다양해지다 보니, 지원과 Vendor의 Driver 역시 존재한다.

2.1 HID (Human Interface Device) Class
    Keyboard, Mouse 및 기타 일반적인 Input Device 이며 대중적으로 많이 사용이 되어지는
    Input Device들을 지원한다.
    이를 이용하여, 다른 Input Device로도 설계가 가능하며 본인의 용도에 맞게 Descriptor를 만들면 될 것이다.

    ClassSubClassProtocol
    03h - HID00h - None
    01h - Boot Interface
    00h - None
    01h - Keyboard
    02h - Mouse
    • 관련예제 
      http://www.usblyzer.com/usb-human-interface-device-hid-class-decoder.htm


    2.2 Hub Class 
      USB Host에서 연결되는 USB Hub를 말하며, USB의 Bridge 역할을 하는 Hub를 사용하기 위한 Class이며,
      이에 관련된 부분을 Descriptors로 구성한다.

      ClassSubClassProtocol
      09h - Hub00h00h - Full-speed Hub
      01h - Hi-speed Hub with single TT
      02h - Hi-speed Hub with multiple TTs


        http://www.usblyzer.com/usb-hub-class-decoder.htm


      2.3 Mass Storage Class
        일반적으로 많이 사용이 되는 USB Storage를 말하며 Window에서는 FAT로 포맷해서 사용한다.
        대중적으로 많이 사용하기 때문에 일반적으로 거의 동일하게 사용이 되며, Linux에서 처음사용한다면, fdisk로 partition 을 먼저 나눈다음에, fat로 포맷을 한 후 사용하는 것이 맞다.
        USB Host에서는 일반적으로 udev를 이용하여 Auto mount 되는 shell script가 제공한다.

        ClassSubClassProtocol
        08h - MSC0x01 - Reduced Block Commands (RBC)
        0x02 - MMC (ATAPI)
        0x05 - SFF-8070i
        0x06 - SCSI transparent command set
        0x50 - Bulk-Only (BOT) Transport

          http://www.usblyzer.com/usb-mass-storage-class-msc-decoder.htm


        2.4 CDC(Communication Device Class)
          USB에서 통신을 하는 일반적인 방법을 말하며, Subclass에 종류가 많으며, 이에 따라서 통신방식도 달라진다.
          현재 USB를 이용하여 Network 및 다양하게 통신 중심으로 나누어지는 Class이기 때문에 반드시 알아둬야할 것이다.
          아래의 usb분석기도 모든 CDC 정보를 가지고 있지 않아 분석이 가능하지 않다.

          ClassSubClass
          02h - CDC01h - Direct Line Control Model
          02h - Abstract Control Model
          03h - Telephone Control Model
          04h - Multi-Channel Control Model
          05h - CAPI Control Model
          06h - Ethernet Networking Control Model
          07h - ATM Networking Control Model
          08h - Wireless Handset Control Model
          09h - Device Management
          0Ah - Mobile Direct Line Model
          0Bh - OBEX


            http://www.usblyzer.com/usb-communication-device-class-cdc-decoder.htm
            http://elixir.free-electrons.com/linux/v4.3.3/source/include/uapi/linux/usb/cdc.h#L17

          • Linux 에서 많이 사용되어지는 CDC Class 
            1. ACM(Abstract Control Model : 주로 RS-232로 사용)
            2. ECM (Ethernet Device Model)
            3. NCM (Network Control Model)
            4. RNDIS(Remote NDIS RNDIS) :  Ethernet Device이며, Host가 Window에서 많이 이용.
            5. MBIM(Mobile Broadband Interface Model) 


            • Driver Source를 확인
            1. drivers/net/usb/Kconfig  
            2. drivers/usb/net/Kconfig 
            3. driver/usb/serial/Kconfig  

              https://github.com/torvalds/linux/blob/master/drivers/net/usb/Kconfig

            • CDC-ACM (USB 위에 RS-232 Emulate한 예제)
            CDC-ACM은 RS-232으로도 통신이 가능하며, 다른 기능이 존재하는 것 같은데, 현재 주로 RS-232로 사용이 많이 되어진다.
            GPS Module로도 이용이 가능

              http://www.atmel.com/images/doc4322.pdf
              https://www.keil.com/pack/doc/mw/USB/html/group__usbh__cdcacm_functions.html

            • CDC- RNDIS의 예제
              http://blog.naver.com/PostView.nhn?blogId=inftee&logNo=60175694218

            **아래정보는 Vault Micro 제품의 CDC 관련 Driver 지원여부이며, 아래 사이트참조.

            • CDC- 기타기능 
            CDC ECM (Ethernet Devices), CDC EEM (Ethernet Emulation Devices) 부터 대용량 데이터 처리를 할 수 있도록 패킷 처리 방식을 개선한 CDC NCM (Network Control Model)까지 기능 별 사양을 정의하고 있다.

              https://en.wikipedia.org/wiki/Ethernet_over_USB



            • USB LTE 
            USB LTE는 Serial Interface (AT Command)와 PPP Interface (Data)로 구분이되어지며, Kernel에서 이를 지원을 해줘야한다.
            퀄컴은 QMI/Rmnet 이라는 Interface를 이용하여 wwan을 만들어 사용한다고한다.
            LG or GCT의 경우는 제조사별로 별도의 Interface driver가 존재한다고 한다.

            Vault Micro 제품
              http://vaultmicro.blogspot.kr/2013/04/usb-network-protocol.html

            WAN Inteface (Protocol)
              https://lede-project.org/docs/user-guide/wan_interface_protocols
              https://en.wikipedia.org/wiki/Wireless_WAN

              USB 3G Dongle

            Device Driver->USB support->USB Serial Converter support
              *   USB Serial Converter support                     (CONFIG_USB_SERIAL=y)
              *   USB driver for GSM and CDMA modems      (CONFIG_USB_SERIAL_OPTION=y)
                  drivers/usb/serial/usb-serial.c
                  drivers/usb/serial/option.c

              https://wiki.openwrt.org/doc/recipes/3gdongle

            Network Configuration

              https://wiki.debian.org/NetworkConfiguration


            2.5 UVC or USB Video Class 

              Host에서 이에 관련된 Class device driver가 필요하다.
              그리고, 주로 Webcam 같은 Video Stream을 전송하는 Device에서 사용이 되어지고 있다.
              이것역시 개별 Version이 있어 각 Version에 따라 성능과 지원기능이 다르므로, 각 Spec을 자세히 참고하자.

                https://docs.microsoft.com/ko-kr/windows-hardware/drivers/stream/usb-video-class-driver-overview
                https://en.wikipedia.org/wiki/USB_video_device_class
                https://en.wikipedia.org/wiki/List_of_USB_video_class_devices



              • Linux UVC Driver

                http://www.ideasonboard.org/uvc/
                https://git.linuxtv.org/pinchartl/uvcvideo.git/
                https://git.linuxtv.org/pinchartl/uvcvideo.git/tree/drivers/usb/gadget?h=uvcvideo-gadget
                https://git.linuxtv.org/


              • USB Video Class 1.5

                https://drive.google.com/open?id=0B_ehveuLi8MVSWh2dnRwQlp0dVk