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