teensy

Teensy

Stars
8

CS 572 Assignment 2 teensy-usb driver

Author: Rebekah Leslie Group: Thomas DuBuisson and John Ochsner


Overview:

Our driver provides the initial steps towards a secure USB storage device for Linux. We use the available dynamic memory on the Teensy device to store data objects supplied by a user-level process. In principle the data objects could be any size, so long as they fit on the device. These data objects are keyed to a user-supplied index. The gadget-side driver displays the index at storage time to demonstrate that the device is operating properly. Our ultimate goal is for the gadget-side driver to perform a private transformation to the data at storage time to protect the data stored on the device.

The teensy device currently supports read and write operations that operate on the data-object at a particular index in the store. We envision adding support for more operations, such as deleting a data object, clearing the entire memory, or querying the device for statistics.

Given the time permitted for the assignment, we were not able to achieve all of our initial goals for the project. The device only handles fixed-size 16-bit data objects and does not perform any transformation to the data prior to storage. However, we were able to complete a framework for accessing the teensy device that we think is robust enough to accomodate the components of the original plan.


Testing the device:

The test script for the device will build and load the driver, build and run all of the tests, then unload the driver before returning. Test failures print an error message, while driver errors (failure to build or load/unload) terminate the script. The script must be run with root privilege.

In this directory, as root, simply type "./runteensy" to execute the script.

For more information about the specific tests performed, please see the test README located in 'tests/README'.

The test scripts are written by Rebekah Leslie. Thomas DuBuisson performed most of the debugging of the driver during development.


Design of the Gadget/Host Interface Author: Entire Team

The host- and gadget- side of the driver communicate over a set of three endpoints. From the host's perspective, there is a bulk-out endpoint for sending control information to the gadget, a bulk-out endpoint for writing data-objects, and a bulk-in endpoint for reading data-objects. When the user requests a particular operation, the host-side driver issues an instruction (currently read or write) over the command endpoint the issues a data request over the appropriate data endpoint (input or output).

GADGET					HOST
	|				|
	|				|
            |      command :: BULK OUT      |
	| <<----------------------------|
	|				|
	|    data output :: BULK OUT	|
	| <<----------------------------|
	|				|
	|     data input :: BULK IN	|
	|---------------------------->>	|
	|				|
	|				|

With only read and write operations, the command endpoint is not strictly necessary (the operations could be associated with the endpoints, so that a bulk-in request is treated as a read and a bulk-out request is treated as a write), however, our design allows for extension to the command set in the future. We already have a placeholder ioctl implementation for deleting a data object and for clearing the store.


Host-side configuration of the device: Author: Rebekah Leslie File: main.c (and ./Makefile)

The host-side configuration provides all of the setup necessary for managing the teensy device and interfacing with USB core. The probe method performs most of the work---we don't want to initialize all of our structures until there is some hope of the device being used. We require that the configuration presented by the USB device precicely match the expected configuration (the four previously discussed endpoints); loading the device will fail otherwise.

In addition to the configuration performed by the driver once loaded, Rebekah researched the mechanics of hotplugging. Running "make install" as root should configure the host system to auto-load the correct driver when the Teensy board is plugged in. There were some issues with this during testing due to conflict with another driver---in this case the driver has to be manually loaded using insmod or modprobe.


Communicating between the gadget and host Author: Thomas DuBuisson

The read and write operations provide the user interface to the device. The host-side driver performs some basic validation of the request submitted by the user, then issues the appropriate message to the gadget-side driver. The gadget-side driver waits for requests to come in and modifies the store as appropriate (using the gadget-side storage library, see below).

In addition to responding to storage requests, the gadget-side driver must handle requests from USB core to identify and describe the the device. This includes specifying the configurations that are supported by the device. We use the Lightweight USB Framework for AVRs (LUFA) library to handle the low-level management of the Teensy device. Though this in principle allows us to focus more attention on the interesting control elements of the gadget-side driver, learning to use the LUFA library was a significant investment in and of itself. Ultimately, we think this is the right choice for creating a robust and comprehensible driver in spite of the high learning curve (after all, the underlying USB protocol is even more difficult to master).


Gadget-side storage and display Author: John Ochsner

We represent the storage of the device as an array of data-objects (currently of a fixed size). The storage library provides an abstraction over this array and performs argument validation (making sure that the specified index is within bounds).

When the gadget-side driver receives a request to access a particular index, the driver displays the specified index on a 4 character hexidecimal display connected to the device. This allows us to demonstrate a connection between a user request and the actual operation of the device.