C D JavaScript Other
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


CS 572 Assignment 2
teensy-usb driver

Author: Rebekah Leslie
Group:  Thomas DuBuisson and John Ochsner


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).

		|				|
		|				|
                |      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

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

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.