How to Use USB Gadget File Storage

Summary

The g_mass_storage driver allows a target device (such as the at91sam9260-ek board) to appear as a USB Mass Storage device to a host system. It allows you to choose either a block device (such as a hard drive, MTD partition, or flash card) or a backing file to act as the backing storage for this device.

The backing file is a regular file that has been formatted to appear like a block device. The g_mass_storage driver can use a properly formatted file as a storage device. This file resides in your filesystem like any other file.

Using NAND flash to store the data for the file storage driver can be problematic. You cannot format NAND flash with a vfat filesystem since it is not wear-leveling and is not aware of bad blocks. If a bad block falls on the partition, then it will cause data errors. JFFS2 is also insufficient because it can only be mounted from an MTD device. Since the USB Mass Storage driver treats the device as a SCSI disk, it loses all MTD properties and JFFS2 cannot be mounted.

The solution is to create a VFAT partitioned backing file on a jffs2 image. The jffs2 image can be mounted on the target machine, and then the backing file can be used by the file storage driver as the backing store. This backup file can even be mounted as a loopback device on the target to allow reading/writing by both the host and target.

IMPORTANT: You should NEVER write to the backing store from the target while the board is attached to the host. This can cause filesystem corruption.

Prerequisites

  • Kernel built with the following options:
    • CONFIG_USB_GADGET=y
  • CONFIG_USB_GADGETFS=m
  • Target RFS containing:
    • modprobe
    • losetup
    • fdisk

Procedure

  1. Create a Backing File - This is a file or device where the data is stored.
  2. Install the g_file_storage module

Creating the Backing File

The backing file is a file in your filesystem that is formatted to look like a block device. It can reside anywhere in your filesystem.

You can use the pre-made backing file here: http://mirror.timesys.com/shared/tony/backingstore

Or, if you wish to create your own, see the website http://www.linux-usb.org/gadget/file_storage.html for detailed instructions.

I used the following values:

8 sectors/track
x heads (tracks/cylinder), where x = <size of backing file in bytes> / 4
1024 cylinders

Installing the module

On the target, install the g_file_storage driver module with the following command:

modprobe g_mass_storage file=<backing file>

Mounting on the Host

Connect the cable between the host and target:

# dmesg | tail
# sudo mkfs.vfat /dev/sdc1
# sudo mkdir /media/OTG
# sudo mount /dev/sdc1 /media/OTG 

Example:

bash# modprobe g_mass_storage file=/mnt/mtd6/backing_file

Tips and Tricks

Mounting Backing File as Loopback Device

If you wish to work on the backing file on your target platform, you can mount the file as a loopback device first.

Instructions for this can be found on the page http://www.linux-usb.org/gadget/file_storage.html

Example:

This example mounts a backing file as a loopback device and pre-formats it with a vfat filesystem.

bash# losetup -o 4096 /dev/loop0 /mnt/mtd6/backing_file
bash# mkfs.vfat /dev/loop0

Additional Resources

Linux USB - Official documentation for File-Backed Storage driver