Andrey Konovalov | f2c2e71 | 2020-02-24 17:13:03 +0100 | [diff] [blame] | 1 | ============== |
| 2 | USB Raw Gadget |
| 3 | ============== |
| 4 | |
| 5 | USB Raw Gadget is a kernel module that provides a userspace interface for |
| 6 | the USB Gadget subsystem. Essentially it allows to emulate USB devices |
| 7 | from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is |
| 8 | currently a strictly debugging feature and shouldn't be used in |
| 9 | production, use GadgetFS instead. |
| 10 | |
| 11 | Comparison to GadgetFS |
| 12 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 13 | |
| 14 | Raw Gadget is similar to GadgetFS, but provides a more low-level and |
| 15 | direct access to the USB Gadget layer for the userspace. The key |
| 16 | differences are: |
| 17 | |
| 18 | 1. Every USB request is passed to the userspace to get a response, while |
| 19 | GadgetFS responds to some USB requests internally based on the provided |
| 20 | descriptors. However note, that the UDC driver might respond to some |
| 21 | requests on its own and never forward them to the Gadget layer. |
| 22 | |
| 23 | 2. GadgetFS performs some sanity checks on the provided USB descriptors, |
| 24 | while Raw Gadget allows you to provide arbitrary data as responses to |
| 25 | USB requests. |
| 26 | |
| 27 | 3. Raw Gadget provides a way to select a UDC device/driver to bind to, |
| 28 | while GadgetFS currently binds to the first available UDC. |
| 29 | |
Andrey Konovalov | 97df5e5 | 2020-05-07 19:06:56 +0200 | [diff] [blame] | 30 | 4. Raw Gadget explicitly exposes information about endpoints addresses and |
| 31 | capabilities allowing a user to write UDC-agnostic gadgets. |
Andrey Konovalov | f2c2e71 | 2020-02-24 17:13:03 +0100 | [diff] [blame] | 32 | |
| 33 | 5. Raw Gadget has ioctl-based interface instead of a filesystem-based one. |
| 34 | |
| 35 | Userspace interface |
| 36 | ~~~~~~~~~~~~~~~~~~~ |
| 37 | |
| 38 | To create a Raw Gadget instance open /dev/raw-gadget. Multiple raw-gadget |
| 39 | instances (bound to different UDCs) can be used at the same time. The |
| 40 | interaction with the opened file happens through the ioctl() calls, see |
| 41 | comments in include/uapi/linux/usb/raw_gadget.h for details. |
| 42 | |
| 43 | The typical usage of Raw Gadget looks like: |
| 44 | |
| 45 | 1. Open Raw Gadget instance via /dev/raw-gadget. |
| 46 | 2. Initialize the instance via USB_RAW_IOCTL_INIT. |
| 47 | 3. Launch the instance with USB_RAW_IOCTL_RUN. |
| 48 | 4. In a loop issue USB_RAW_IOCTL_EVENT_FETCH calls to receive events from |
| 49 | Raw Gadget and react to those depending on what kind of USB device |
| 50 | needs to be emulated. |
| 51 | |
Andrey Konovalov | 61d2658 | 2020-05-07 19:06:58 +0200 | [diff] [blame] | 52 | Note, that some UDC drivers have fixed addresses assigned to endpoints, and |
| 53 | therefore arbitrary endpoint addresses can't be used in the descriptors. |
| 54 | Nevertheles, Raw Gadget provides a UDC-agnostic way to write USB gadgets. |
| 55 | Once a USB_RAW_EVENT_CONNECT event is received via USB_RAW_IOCTL_EVENT_FETCH, |
| 56 | the USB_RAW_IOCTL_EPS_INFO ioctl can be used to find out information about |
| 57 | endpoints that the UDC driver has. Based on that information, the user must |
| 58 | chose UDC endpoints that will be used for the gadget being emulated, and |
| 59 | properly assign addresses in endpoint descriptors. |
| 60 | |
| 61 | You can find usage examples (along with a test suite) here: |
| 62 | |
| 63 | https://github.com/xairy/raw-gadget |
| 64 | |
| 65 | Internal details |
| 66 | ~~~~~~~~~~~~~~~~ |
| 67 | |
| 68 | Currently every endpoint read/write ioctl submits a USB request and waits until |
| 69 | its completion. This is the desired mode for coverage-guided fuzzing (as we'd |
| 70 | like all USB request processing happen during the lifetime of a syscall), |
| 71 | and must be kept in the implementation. (This might be slow for real world |
| 72 | applications, thus the O_NONBLOCK improvement suggestion below.) |
| 73 | |
Andrey Konovalov | f2c2e71 | 2020-02-24 17:13:03 +0100 | [diff] [blame] | 74 | Potential future improvements |
| 75 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 76 | |
Andrey Konovalov | 61d2658 | 2020-05-07 19:06:58 +0200 | [diff] [blame] | 77 | - Report more events (suspend, resume, etc.) through USB_RAW_IOCTL_EVENT_FETCH. |
Andrey Konovalov | f2c2e71 | 2020-02-24 17:13:03 +0100 | [diff] [blame] | 78 | |
| 79 | - Support O_NONBLOCK I/O. |
Andrey Konovalov | 61d2658 | 2020-05-07 19:06:58 +0200 | [diff] [blame] | 80 | |
| 81 | - Support USB 3 features (accept SS endpoint companion descriptor when |
| 82 | enabling endpoints; allow providing stream_id for bulk transfers). |
| 83 | |
| 84 | - Support ISO transfer features (expose frame_number for completed requests). |