]>
Commit | Line | Data |
---|---|---|
f2c2e717 AK |
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 | ||
97df5e57 AK |
30 | 4. Raw Gadget explicitly exposes information about endpoints addresses and |
31 | capabilities allowing a user to write UDC-agnostic gadgets. | |
f2c2e717 AK |
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 | ||
61d2658d AK |
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 | ||
f2c2e717 AK |
74 | Potential future improvements |
75 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
76 | ||
61d2658d | 77 | - Report more events (suspend, resume, etc.) through USB_RAW_IOCTL_EVENT_FETCH. |
f2c2e717 AK |
78 | |
79 | - Support O_NONBLOCK I/O. | |
61d2658d AK |
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). |