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

Modern USB Gadget with Custom USB Functions

Nov 18, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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!