June 8, 2025
Mass storage over usb (Raspberry pi)

Mass storage over usb (Raspberry pi)

We recently published an couple of articles on Ethernet over USB, Virtual uart over usb, and Hid device over usb using the USB gadgets functionality in Linux, which you can find here. Now, we are expanding on that by implementing a Mass storage on the same USB port that is running the Ethernet USB gadget.

Understanding USB Mass Storage Gadgets

A USB mass storage gadget allows a device to emulate a USB storage device, such as a flash drive or external hard disk. This means you can connect your Raspberry Pi to another computer and have it appear as an external storage device. The benefits include:

Implementing Mass storage over usb

Connect the Usb Type-C port Raspberry pi 4 to pc.

Next , we will need to enable the dwc2 overlay by modifying the boot configuration. Open the config.txt file by :

sudo nano /boot/config.txt

# Add the following line at the end:

dtoverlay=dwc2

# Save and exit (CTRL+X, then Y).

Next , we will need to create usb massstorage gadget by executing following script :

#!/bin/bash

GADGETDIR='mygadget'
SERIAL=`cat /proc/cpuinfo | grep Serial | cut -d ' ' -f 2`
HOSTPREFIX="02"
DEVICEPREFIX="06"
MANUFACTURER="nobody"
PRODUCT='nothing'

#MASS_STORAGE_FILE="/piusb.bin" # Path to the mass storage file / partation
MASS_STORAGE_FILE="/dev/mmcblk0p2" # path root partation
MASS_STORAGE_READONLY=1 # Set to 0 for read/write

# Calculate MAC addresses based on unique serial number of raspberry pi 
padded='00000000000000'$SERIAL
basemac=${padded: -12} # last 12 characters
hostmac=$HOSTPREFIX:${basemac: -10:2}:${basemac: -8:2}:${basemac: -6:2}:${basemac: -4:2}:${basemac: -2:2}
devmac=$DEVICEPREFIX:${basemac: -10:2}:${basemac: -8:2}:${basemac: -6:2}:${basemac: -4:2}:${basemac: -2:2}

# Check if running as root
if [ "$(id -u)" -ne 0 ]; then
    echo "Must be root" >&2
    exit 1
fi

# load the libcomposite module

modprobe libcomposite

mkdir -p /sys/kernel/config/usb_gadget/$GADGETDIR
cd /sys/kernel/config/usb_gadget/$GADGETDIR || exit

echo 0x1d6b > idVendor
echo 0x0104 > idProduct
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB
mkdir -p strings/0x409
echo $SERIAL > strings/0x409/serialnumber
echo $MANUFACTURER > strings/0x409/manufacturer
echo $PRODUCT > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Config 1: ECM network" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
mkdir -p functions/ecm.usb0
# Assign static mac address
echo $hostmac > functions/ecm.usb0/host_addr
echo $devmac > functions/ecm.usb0/dev_addr
ln -s functions/ecm.usb0 configs/c.1/

# this will create the virtual serial port

ln -s functions/acm.usb0 configs/c.1/  

# for mass storage 


# Create Mass Storage function (read/write)
mkdir -p functions/mass_storage.usb0
echo $MASS_STORAGE_FILE > functions/mass_storage.usb0/lun.0/file
echo $MASS_STORAGE_READONLY > functions/mass_storage.usb0/lun.0/ro # 0 for read/write
ln -s functions/mass_storage.usb0 configs/c.1/

ls /sys/class/udc > UDC

Limitation

When a Raspberry Pi is mounted as a USB mass storage device, write operations can be risky, especially if the underlying storage medium is being accessed by the operating system simultaneously. Here are some key points regarding the reliability of write operations:

  • Data Corruption: If the filesystem is being accessed both as a USB mass storage device and by the operating system (e.g., for reading or writing files), this can lead to data corruption.
  • Unmounting: Always unmount the device properly before disconnecting it to prevent data loss. If the device is not unmounted, changes made during the session might not be written properly to the storage.
  • File System: The reliability of write operations also depends on the file system being used. Some file systems are more resilient to unexpected disconnections or power failures.
  • Caching: Depending on the configuration, writes might be cached and not immediately flushed to disk, leading to a potential loss of data if the device is removed unexpectedly.
  • Kernel Bugs: While less common, bugs in the kernel or USB subsystem could also affect the reliability of write operations.

Conclusion

Transforming your Raspberry Pi into a USB mass storage gadget using the usb_gadget interface offers a powerful and flexible way to manage external storage. By following this guide, you can create a custom USB storage solution that enhances your Raspberry Pi’s capabilities while deepening your understanding of USB device management. Whether for personal use or educational purposes, this project highlights the incredible versatility of the Raspberry Pi platform. Happy tinkering!

Leave a Reply

Your email address will not be published. Required fields are marked *