62
Modern USB Gadget with Custom USB Functions... ...and its integration with systemd Andrzej Pietrasiewicz <[email protected]> ELC 2019

Modern USB Gadget with Custom USB Functions

  • Upload
    others

  • View
    20

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Modern USB Gadget with Custom USB Functions

Modern USB Gadget with Custom USB Functions...

...and its integration with systemd

Andrzej Pietrasiewicz <[email protected]> ELC 2019

Page 2: Modern USB Gadget with Custom USB Functions

2

USB Device user?

A Linux machine connected to a PC

Page 3: Modern USB Gadget with Custom USB Functions

3

Overview

● Composition and components+ your own USB functionality

● Tools

● systemd integration+ your own USB functionality

Page 4: Modern USB Gadget with Custom USB Functions

4

Composition and components

Page 5: Modern USB Gadget with Custom USB Functions

5

Endpoints

● Control

● Bulk

● Interrupt

● Isochronous

USB HOST

USB DEVICE

0 0 1 1 2 2

Data for “1”

Page 6: Modern USB Gadget with Custom USB Functions

6

Interface

● Collection of endpoints for a particular purpose

● Implemented as “USB function” in Linux kernel

Page 7: Modern USB Gadget with Custom USB Functions

7

Configuration

● Collection of 1+ interface(s)

● Device contains 1+ configuration(s)

– Only 1 active at a time

– Rarely > 1

Page 8: Modern USB Gadget with Custom USB Functions

8

FunctionFS

● A USB function

● A filesystem with ep0 and epX….

Page 9: Modern USB Gadget with Custom USB Functions

9

Theoretical # combinations

(201 )+(202 )+(203 )+...+(2020)=ALOT

Page 10: Modern USB Gadget with Custom USB Functions

10

Tools

Page 11: Modern USB Gadget with Custom USB Functions

11

Configfs

● /sys/kernel/config/usb_gadget

● mkdir, echo, ln -s, rmdir

Page 12: Modern USB Gadget with Custom USB Functions

12

mkdir g1cd g1

echo 0x1d6b > idVendorecho 0x104 > idProduct

mkdir strings/0x409 # US English, others rarely seenecho "Collabora" > strings/0x409/manufacturerecho "ECM" > strings/0x409/product

mkdir configs/c.1 # dot and number mandatory

mkdir functions/ecm.usb0

ln -s functions/ecm.usb0/ configs/c.1/

# bind!# ls /sys/class/udc to see available UDCsecho 12480000.hsotg > UDC

Page 13: Modern USB Gadget with Custom USB Functions

13

mkdir g1cd g1

echo 0x1d6b > idVendorecho 0x104 > idProduct

mkdir strings/0x409 # US English, others rarely seenecho "Collabora" > strings/0x409/manufacturerecho "ECM" > strings/0x409/product

mkdir configs/c.1 # dot and number mandatory

mkdir functions/ecm.usb0

ln -s functions/ecm.usb0/ configs/c.1/

# bind!# ls /sys/class/udc to see available UDCsecho 12480000.hsotg > UDC

Page 14: Modern USB Gadget with Custom USB Functions

14

mkdir g1cd g1

echo 0x1d6b > idVendorecho 0x104 > idProduct

mkdir strings/0x409 # US English, others rarely seenecho "Collabora" > strings/0x409/manufacturerecho "ECM" > strings/0x409/product

mkdir configs/c.1 # dot and number mandatory

mkdir functions/ecm.usb0

ln -s functions/ecm.usb0/ configs/c.1/

# bind!# ls /sys/class/udc to see available UDCsecho 12480000.hsotg > UDC

Page 15: Modern USB Gadget with Custom USB Functions

15

mkdir g1cd g1

echo 0x1d6b > idVendorecho 0x104 > idProduct

mkdir strings/0x409 # US English, others rarely seenecho "Collabora" > strings/0x409/manufacturerecho "ECM" > strings/0x409/product

mkdir configs/c.1 # dot and number mandatory

mkdir functions/ecm.usb0

ln -s functions/ecm.usb0/ configs/c.1/

# bind!# ls /sys/class/udc to see available UDCsecho 12480000.hsotg > UDC

Page 16: Modern USB Gadget with Custom USB Functions

16

mkdir g1cd g1

echo 0x1d6b > idVendorecho 0x104 > idProduct

mkdir strings/0x409 # US English, others rarely seenecho "Collabora" > strings/0x409/manufacturerecho "ECM" > strings/0x409/product

mkdir configs/c.1 # dot and number mandatory

mkdir functions/ecm.usb0

ln -s functions/ecm.usb0/ configs/c.1/

# bind!# ls /sys/class/udc to see available UDCsecho 12480000.hsotg > UDC

Page 17: Modern USB Gadget with Custom USB Functions

17

mkdir g1cd g1

echo 0x1d6b > idVendorecho 0x104 > idProduct

mkdir strings/0x409 # US English, others rarely seenecho "Collabora" > strings/0x409/manufacturerecho "ECM" > strings/0x409/product

mkdir configs/c.1 # dot and number mandatory

mkdir functions/ecm.usb0

ln -s functions/ecm.usb0/ configs/c.1/

# bind!# ls /sys/class/udc to see available UDCsecho 12480000.hsotg > UDC

Page 18: Modern USB Gadget with Custom USB Functions

18

gt

● github.com/kopasiak/gt

● github.com/libusbgx/libusbgx.git

● gadget “schemes”

Page 19: Modern USB Gadget with Custom USB Functions

19

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "ECM"; });functions : { ecm_usb0 : { instance = "usb0"; type = "ecm"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ecm.usb0"; function = "ecm_usb0"; } ); } );

Page 20: Modern USB Gadget with Custom USB Functions

20

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "ECM"; });functions : { ecm_usb0 : { instance = "usb0"; type = "ecm"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ecm.usb0"; function = "ecm_usb0"; } ); } );

Page 21: Modern USB Gadget with Custom USB Functions

21

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "ECM"; });functions : { ecm_usb0 : { instance = "usb0"; type = "ecm"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ecm.usb0"; function = "ecm_usb0"; } ); } );

Page 22: Modern USB Gadget with Custom USB Functions

22

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "ECM"; });functions : { ecm_usb0 : { instance = "usb0"; type = "ecm"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ecm.usb0"; function = "ecm_usb0"; } ); } );

Page 23: Modern USB Gadget with Custom USB Functions

23

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "ECM"; });functions : { ecm_usb0 : { instance = "usb0"; type = "ecm"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ecm.usb0"; function = "ecm_usb0"; } ); } );

Page 24: Modern USB Gadget with Custom USB Functions

24

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "ECM"; });functions : { ecm_usb0 : { instance = "usb0"; type = "ecm"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ecm.usb0"; function = "ecm_usb0"; } ); } );

Page 25: Modern USB Gadget with Custom USB Functions

25

systemd integration

Page 26: Modern USB Gadget with Custom USB Functions

26

systemd

● Various units

– service, mount, target, socket, ...

● Tracked dependencies

● High parallelization

● Lazy initialization (socket units)

Page 27: Modern USB Gadget with Custom USB Functions

27

The “glue layer”

● usb-gadget.target

● udev event

Page 28: Modern USB Gadget with Custom USB Functions

28

The “glue layer”

● usb-gadget.target

● udev event

[Unit] Description=Hardware activated USB gadget Documentation=man:systemd.special(7)

Page 29: Modern USB Gadget with Custom USB Functions

29

The “glue layer”

● usb-gadget.target

● udev event

[Unit] Description=Hardware activated USB gadget Documentation=man:systemd.special(7)

SUBSYSTEM=="udc", ACTION=="add", TAG+="systemd", \ENV{SYSTEMD_WANTS}+="usb-gadget.target"

Page 30: Modern USB Gadget with Custom USB Functions

30

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

Page 31: Modern USB Gadget with Custom USB Functions

31

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

Page 32: Modern USB Gadget with Custom USB Functions

32

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

Page 33: Modern USB Gadget with Custom USB Functions

33

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

Page 34: Modern USB Gadget with Custom USB Functions

34

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

Page 35: Modern USB Gadget with Custom USB Functions

35

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

systemctl [en|dis]able usb-gadget.service

Page 36: Modern USB Gadget with Custom USB Functions

36

Service unit[Unit]Description=Load USB gadget scheme for ecmRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load ecm.scheme ecmRemainAfterExit=yesExecStop=/bin/gt rm -rf ecmType=simple

[Install]WantedBy=usb-gadget.target

systemctl [en|dis]able usb-gadget.service

Page 37: Modern USB Gadget with Custom USB Functions

37

Service unit templatized[Unit]Description=Load USB gadget scheme for %iRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load %i.scheme %iRemainAfterExit=yesExecStop=/bin/gt rm -rf %iType=simple

[Install]WantedBy=usb-gadget.target

Page 38: Modern USB Gadget with Custom USB Functions

38

Service unit templatized[Unit]Description=Load USB gadget scheme for %iRequires=sys-kernel-config.mountAfter=sys-kernel-config.mountDefaultDependencies=no

[Service]ExecStart=/bin/gt load %i.scheme %iRemainAfterExit=yesExecStop=/bin/gt rm -rf %iType=simple

[Install]WantedBy=usb-gadget.target

systemctl [en|dis]able [email protected]

Page 39: Modern USB Gadget with Custom USB Functions

39

systemd integrationYour own USB function

Page 40: Modern USB Gadget with Custom USB Functions

40

FunctionFS vs systemd

● Gadget scheme

● Service unit (create gadget, gt load -o)

● Mount unit (FunctionFS instance)

● Socket unit (start its service unit, enable the gadget)

● Service unit (spawn userspace daemon)

Page 41: Modern USB Gadget with Custom USB Functions

41

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "MTP Gadget"; });functions : { ffs_mtp : { instance = "mtp"; type = "ffs"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ffs.mtp"; function = "ffs_mtp"; } ); } );

Page 42: Modern USB Gadget with Custom USB Functions

42

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "MTP Gadget"; });functions : { ffs_mtp : { instance = "mtp"; type = "ffs"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ffs.mtp"; function = "ffs_mtp"; } ); } );

Page 43: Modern USB Gadget with Custom USB Functions

43

attrs : { idVendor = 0x1D6B; idProduct = 0x104;};strings = ( { lang = 0x409; manufacturer = "Collabora"; product = "MTP Gadget"; });functions : { ffs_mtp : { instance = "mtp"; type = "ffs"; };};

configs = ( { id = 1; name = "c"; functions = ( { name = "ffs.mtp"; function = "ffs_mtp"; } ); } );

Page 44: Modern USB Gadget with Custom USB Functions

44

Mount unit[Unit]Description=FunctionFS instance for ffs_mtpRequires=usb-gadget-ffs@ffs_mtp.serviceAfter=usb-gadget-ffs@ffs_mtp.serviceBefore=ffs@ffs_mtp.socket

[Mount]What=mtpWhere=/run/ffs_mtpType=functionfsOptions=defaultsTimeoutSec=5

Page 45: Modern USB Gadget with Custom USB Functions

45

Mount unit[Unit]Description=FunctionFS instance for ffs_mtpRequires=usb-gadget-ffs@ffs_mtp.serviceAfter=usb-gadget-ffs@ffs_mtp.serviceBefore=ffs@ffs_mtp.socket

[Mount]What=mtpWhere=/run/ffs_mtpType=functionfsOptions=defaultsTimeoutSec=5

Page 46: Modern USB Gadget with Custom USB Functions

46

Mount unit[Unit]Description=FunctionFS instance for ffs_mtpRequires=usb-gadget-ffs@ffs_mtp.serviceAfter=usb-gadget-ffs@ffs_mtp.serviceBefore=ffs@ffs_mtp.socket

[Mount]What=mtpWhere=/run/ffs_mtpType=functionfsOptions=defaultsTimeoutSec=5

Page 47: Modern USB Gadget with Custom USB Functions

47

Mount unit[Unit]Description=FunctionFS instance for ffs_mtpRequires=usb-gadget-ffs@ffs_mtp.serviceAfter=usb-gadget-ffs@ffs_mtp.serviceBefore=ffs@ffs_mtp.socket

[Mount]What=mtpWhere=/run/ffs_mtpType=functionfsOptions=defaultsTimeoutSec=5

Page 48: Modern USB Gadget with Custom USB Functions

48

Socket unit[Unit]Description=USB FunctionFS socket for %iRequires=run-%i.mountAfter=run-%i.mountDefaultDependencies=no

[Socket]ListenUSBFunction=/run/%iService=%i.serviceExecStartPost=/bin/gt enable %iTriggerLimitIntervalSec=0

[Install]WantedBy=usb-gadget.target

Page 49: Modern USB Gadget with Custom USB Functions

49

Socket unit[Unit]Description=USB FunctionFS socket for %iRequires=run-%i.mountAfter=run-%i.mountDefaultDependencies=no

[Socket]ListenUSBFunction=/run/%iService=%i.serviceExecStartPost=/bin/gt enable %iTriggerLimitIntervalSec=0

[Install]WantedBy=usb-gadget.target

Page 50: Modern USB Gadget with Custom USB Functions

50

Socket unit[Unit]Description=USB FunctionFS socket for %iRequires=run-%i.mountAfter=run-%i.mountDefaultDependencies=no

[Socket]ListenUSBFunction=/run/%iService=%i.serviceExecStartPost=/bin/gt enable %iTriggerLimitIntervalSec=0

[Install]WantedBy=usb-gadget.target

Page 51: Modern USB Gadget with Custom USB Functions

51

Socket unit[Unit]Description=USB FunctionFS socket for %iRequires=run-%i.mountAfter=run-%i.mountDefaultDependencies=no

[Socket]ListenUSBFunction=/run/%iService=%i.serviceExecStartPost=/bin/gt enable %iTriggerLimitIntervalSec=0

[Install]WantedBy=usb-gadget.target

Page 52: Modern USB Gadget with Custom USB Functions

52

Socket unit[Unit]Description=USB FunctionFS socket for %iRequires=run-%i.mountAfter=run-%i.mountDefaultDependencies=no

[Socket]ListenUSBFunction=/run/%iService=%i.serviceExecStartPost=/bin/gt enable %iTriggerLimitIntervalSec=0

[Install]WantedBy=usb-gadget.target

Page 53: Modern USB Gadget with Custom USB Functions

53

Socket unit[Unit]Description=USB FunctionFS socket for %iRequires=run-%i.mountAfter=run-%i.mountDefaultDependencies=no

[Socket]ListenUSBFunction=/run/%iService=%i.serviceExecStartPost=/bin/gt enable %iTriggerLimitIntervalSec=0

[Install]WantedBy=usb-gadget.target

Page 54: Modern USB Gadget with Custom USB Functions

54

Service unit

[Unit]Description=MTP responderStartLimitIntervalSec=0

[Service]Type=simpleExecStart=/usr/bin/cmtp-responderUSBFunctionDescriptors=/etc/cmtp-responder/descsUSBFunctionStrings=/etc/cmtp-responder/strsKillMode=processRestartSec=3Restart=on-failure

Page 55: Modern USB Gadget with Custom USB Functions

55

Service unit

[Unit]Description=MTP responderStartLimitIntervalSec=0

[Service]Type=simpleExecStart=/usr/bin/cmtp-responderUSBFunctionDescriptors=/etc/cmtp-responder/descsUSBFunctionStrings=/etc/cmtp-responder/strsKillMode=processRestartSec=3Restart=on-failure

Page 56: Modern USB Gadget with Custom USB Functions

56

Service unit

[Unit]Description=MTP responderStartLimitIntervalSec=0

[Service]Type=simpleExecStart=/usr/bin/cmtp-responderUSBFunctionDescriptors=/etc/cmtp-responder/descsUSBFunctionStrings=/etc/cmtp-responder/strsKillMode=processRestartSec=3Restart=on-failure

Page 57: Modern USB Gadget with Custom USB Functions

57

Service unit

[Unit]Description=MTP responderStartLimitIntervalSec=0

[Service]Type=simpleExecStart=/usr/bin/cmtp-responderUSBFunctionDescriptors=/etc/cmtp-responder/descsUSBFunctionStrings=/etc/cmtp-responder/strsKillMode=processRestartSec=3Restart=on-failure

include/uapi/linux/usb/functionfs.h

Page 58: Modern USB Gadget with Custom USB Functions

58

Descriptors and strings

● github.com/kopasiak/gt/pull/8

● Declarative config → blob

– USBFunctionDescriptors, USBFunctionStrings

Page 59: Modern USB Gadget with Custom USB Functions

59

Demo

Page 60: Modern USB Gadget with Custom USB Functions

60

MTP Device

● github.com/cmtp-responder/cmtp-responder.git

● Odroid U2

Page 61: Modern USB Gadget with Custom USB Functions

61

Summary

● Composition and components+ your own USB functionality

● Tools

● systemd integration+ your own USB functionality

Page 62: Modern USB Gadget with Custom USB Functions

62

Thank you!