Mass Storage Gadget Guide
Mass Storage Gadget Guide
A Beginner's Guide
Table of Contents
1 Colophon..........................................................................................................................................4
2 Introduction......................................................................................................................................5
2.1 What’s Not Covered..................................................................................................................5
2.2 Requirements:...........................................................................................................................5
2.3 Conventions..............................................................................................................................6
3 The Mass Storage Gadget.................................................................................................................7
3.1 What it Does Do........................................................................................................................7
3.2 What it Does Not Do.................................................................................................................7
3.3 Restrictions...............................................................................................................................7
3.4 How It Works And Why Write Access Is Bad..........................................................................8
3.5 A Warning.................................................................................................................................8
4 The Backing Store............................................................................................................................9
4.1 Using An Entire Device............................................................................................................9
4.2 Using A Partition.....................................................................................................................10
4.2.1 Creating A Partition Based Backing Store......................................................................10
4.3 Using A File............................................................................................................................11
4.3.1 Creating A File Based Backing Store..............................................................................11
4.4 Partitioning And Formatting The Backing Store....................................................................12
4.5 Adding Content To The Backing Store...................................................................................13
4.5.1 From The Zero................................................................................................................13
4.5.2 From The USB Host........................................................................................................13
5 Configure The Zero........................................................................................................................14
5.1 All Methods.............................................................................................................................14
5.2 Using The g_mass_storage Module........................................................................................15
5.2.1 Why.................................................................................................................................15
5.2.2 Why Not..........................................................................................................................15
5.2.3 How.................................................................................................................................15
5.2.4 Module Parameters..........................................................................................................16
5.3 Using The libcomposite Module And configfs.......................................................................17
5.3.1 Why.................................................................................................................................17
5.3.2 Why Not..........................................................................................................................17
5.3.3 How.................................................................................................................................17
5.3.4 Bash Script Example.......................................................................................................19
5.4 Verify It’s Working..................................................................................................................20
6 Troubleshooting..............................................................................................................................21
6.1 Configure The Secondary Channel into The Zero..................................................................21
6.1.1 The 4B – A Special Case.................................................................................................21
6.1.2 Serial Port........................................................................................................................21
6.1.3 Network...........................................................................................................................22
6.1.4 Serial Over USB..............................................................................................................23
6.2 The Zero Does Not Boot.........................................................................................................24
6.2.1 All cases..........................................................................................................................24
6.2.2 Power From USB Host Only...........................................................................................24
6.2.3 Zero With Its Own PSU..................................................................................................24
6.3 The USB Host Does Not Detect The Mass Storage Gadget...................................................25
6.4 The USB Host Cannot Mount The Backing Store..................................................................26
6.5 The USB Host Cannot Write To The Backing Store...............................................................27
6.6 Changes Made To The Contents Of The Backing Store On One Side Are Not Visible On The
Other.............................................................................................................................................28
7 Advanced Usage.............................................................................................................................29
7.1 Making A File Based Backing Store More Secure.................................................................29
7.2 Changing The Backing Store On The Fly...............................................................................30
7.2.1 When Using g_mass_storage..........................................................................................30
7.2.2 When Using libcomposite and configfs..........................................................................30
7.3 Putting The Backing Store On A Network Server..................................................................31
7.3.1 File Based Backing Store................................................................................................31
7.3.2 Partition Or Device Based Backing Store.......................................................................31
7.4 Making The Zero More Robust..............................................................................................32
7.4.1 Adding a Shutdown Button.............................................................................................32
7.4.2 Make The Root Partition Read Only...............................................................................33
1 Colophon
This document is Copyright 2021 and released under a Creative Commons Attribution-
NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) license (see
https://creativecommons.org/licenses/by-nc-sa/4.0/)
2 Introduction
This is a guide to using the USB mass storage gadget functionality on Raspberry Pi models that
support it.
It is assumed that the reader has a basic familiarity with the Linux command line, at least one text
editor, and with partitioning and formatting discs. Desktop users will need to open a terminal to
execute many of the commands in this guide.
2.2 Requirements:
• Raspberry Pi (any model) and the normal accessories to act as the USB host.
• A Raspberry Pi zero, zeroW, zeroWH, A, A+, 3A+, or 4B and the normal accessories.
• A user account on both Pi with permission to use sudo or the ability to login as root.
• An appropriate USB cable:
◦ zero, zeroW, zeroWH: USB A male to micro B male charge and sync.
◦ A, A+, 3A+: USB A male to A male.
◦ 4B: USB C male to USB A male.
• Optional but highly recommended for troubleshooting:
◦ zero and zeroW: GPIO headers fitted.
◦ Three female to female jumper (Dupont) wires.
◦ A second channel into the Pi running in gadget mode.
▪ zeroW(H), 3A+: the onboard WiFi or serial port.
▪ 4B: the onboard WiFi, onboard Ethernet, or serial port.
▪ Others: serial port.
1 The configuration used with a 4B may work but has not been tested. The Pi 400 cannot be powered via its GPIO
header.
2.3 Conventions
Text like this indicates input to or output from the command line.
Text like this also refers to full or partial commands but is not generally intended to be entered
into the command line as is.
“SD card” refers equally to full size and micro SD cards.
“zero” refers to the Pi running the mass storage gadget. Where other models require different
configurations this will be noted.
“backing store”, “shared storage” both refer to the storage exposed to the USB host from the zero.
3 The Mass Storage Gadget
3.3 Restrictions
The mass storage gadget cannot be used with:
• Any PI model that has more than one onboard USB port (4B excepted).
• A USB hub downstream of the zero4.
• Any single USB port Pi model that boots from a USB device5.
The 4B only supports running the mass storage gadget on its USB C port however there are
potential issues with this:
• If your USB host cannot provide sufficient current for the 4B it will need to have its own
PSU. This can be achieved by either powering it via the GPIO header or a suitable Y cable.
• When using a separate PSU for the 4B and the USB host there is a risk of back powering
the host. Use a modified USB cable or adapter with the +ve line cut to avoid this.
• While the connector is USB C, the 4B only provides a USB 2 connection and does not
support USB PD.
• “E marked” cables are known to cause problems with early revision 4Bs.
2 If you must have USB connected storage that has safe simultaneous write access from both sides of the USB link,
use the ethernet gadget and run a samba server on the zero.
3 The 4B can do this but there is little point in it.
4 Including any HATs or HAT like devices that connect via test points to provide additional USB ports.
5 Including via USB network adapters.
3.4 How It Works And Why Write Access Is Bad
This is going to get technical.
The mass storage gadget provides a low level block device to the USB host. The host accesses the
backing store by requesting reads from/writes to it of N bytes/blocks starting at address A. The OS
on the USB host then processes this data to pass the requested file6 to the application that needs it.
The mass storage gadget has no knowledge of which files and directories are being accessed. It also
has no knowledge (and no way to find out) when any given file access has completed.
Writing is safe if only the writing side has the backing store mounted. It is not safe if both sides
have it mounted and are allowing writing nor is it safe if one side has it mounted read/write and the
other read only.
Modern OS7 use both read and write caching8.
Caches on on the USB host and the zero are not, and cannot be, kept in sync.
While the mass storage gadget knows which blocks/bytes have been changed by the USB host it
does not, and cannot, know which files or directories those are part of. It also has no knowledge of
whether all the data to be written has been sent or if there is more to come.
The mass storage gadget is unaware of any changes made by the zero.
The USB host is unaware of any changes made by the zero, the OS on the zero is unaware of any
changes made by the USB host.
Because of the above, writing from one or both sides while the other has it mounted will cause
problems including:
• Files deleted from one side still being present on the other.
• Files added from one side not being shown on the other.
• Files moved or renamed from one side still showing the old name or location on the other.
• File contents being overwritten.
• General file or file system corruption.
3.5 A Warning
The zero is still a full linux computer. Removing power (e.g. by disconnecting it from the USB
host) without first performing a clean shutdown will lead to lost or corrupted data, both within the
backing store and in the zero’s OS storage.
Both fallocate and dd produce unformatted files i.e. they do not contain an useable file system.
With some file system types12, mkfs can create the file and the file system it contains in one
operation. mkfs does not create boot sectors and partition tables. Many USB hosts will see the
backing store as uninitialised and unformatted.13
To create a 1GB file based backing store in the current directory:
• Using fallocate:
fallocate -l 1g fallocate.img
• Using dd:
dd if=/dev/zero of=dd.img bs=1M count=1K
bs is the block/buffer size, count is the number of blocks desired. See man dd.
• Using mkfs:
mkfs -t vfat -C mkfs.img 1048576
Size is specified in blocks. Block size can vary between file systems. Some allow it to be
specified.
10 Subject to the size of the file system or partition containing it and any limitations of that filesystem.
11 Excluding taking an image of an existing drive/partition/file system.
12 See man pages for mkfs, mkdosfs, mke2fs, etc.
13 Most linux USB hosts will be able to mount it using the device node for the drive e.g. /dev/sda.
4.4 Partitioning And Formatting The Backing Store
If you created the backing store with mkfs this step can be skipped unless you need, or want, it to
contain a partition table.
The simplest method and the one least likely to cause complications with USB hosts is to pass the
raw backing store file to the mass storage gadget then initialise, partition, and format from the USB
host.
To initialise, partition, and format the backing store on the zero:
1. Attach the backing store to a loop device14:
sudo losetup --show -fP /path/to/backing-store
15 And removing.
5 Configure The Zero
This can be done either by logging in to the zero or by mounting its SD card in a reader attached to
the USB host. All paths below assume logging in to the zero, adjust as needed if using the latter
method.
2. Using your preferred text editor add the following to the end of /boot/config.txt
[all]
dtoverlay=dwc2,dr_mode=peripheral
On next boot your OS will use the dwc2 driver in the correct mode to support operation as a USB
gadget.
,dr_mode=peripheral is optional on zero, zeroW(H), and the 4B16. It is mandatory on A, A+, and
3A+ as theses are hardwired to host mode and the ID pin is not present on their USB A connectors.
5.2.3 How
1. Apply the steps in section 5.1
2. Open root’s crontab:
sudo crontab -e
Specify whether a backing store is presented to the USB host by emulating a CD-
ROM drive.
b can be “n”, “N”, or “0” for no; “y”, “Y”, or “1” for yes. The default is no.
• file=filename[,filename…]
Path to the file or block device used for the backing store. Multiple values may be
specified up to the default maximum of eight17. If removable is not set to on, a file
must be provided.
Each file will be presented to the USB host as a separate mass storage device.
• removable=b[,b…]
Specify whether a backing store is presented to the USB host as a device with
removable media.
b can be “n”, “N”, or “0” for no; “y”, “Y”, or “1” for yes. The default is no.
• ro=b[,b…]
Specify whether a backing store is presented to the USB host as a read only device.
b can be “n”, “N”, or “0” for no; “y”, “Y”, or “1” for yes.
The default for emulated CD-ROM devices is yes, for all others it is no. If the
backing store cannot be opened for writing the ro parameter will fall back to being
on.
Other parameters can be left at their default values and not specifically included.
5.3.3 How
This is a step by step guide as would be typed at a terminal. In practise you’ll probably want to put
this in a script19.
1. Apply the steps in section 5.1
2. Become root:
sudo -i
3. Load libcomposite:
modprobe libcomposite
If you know it, use the zero’s serial number. Change the other strings to taste.
8. Initial device configuration:
mkdir -p configs/c.1/strings/0x409
echo "Config 1: Mass Storage" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
The output should show an21 additional sd device or sr22 Device and it’s associated
partitions.
21 Or one per file specified if using more than one backing store.
22 If the gadget has been configured with cdrom=y
6 Troubleshooting
6.1.3 Network
Zero, A, and A+ models lack onboard networking so cannot use this method.
ZeroW, zeroWH, 3A+, and 4B models can use their onboard WiFi.
The 4B can also use its onboard ethernet.
Configuration is straight forward:
1. Set up networking on the zero in the usual way.25
2. Enable ssh on the zero.26
3. Reboot the zero.
3. Reboot.
You can now login to the zero with screen.28 Use /dev/ttyACM0 rather than /dev/serial0. If that
fails check which serial device has been assigned by the OS.
29 If the USB host is a Raspberry Pi this will make no difference. No current model Pi does per port USB current
limiting.
6.3 The USB Host Does Not Detect The Mass Storage Gadget
• Check that the zero has booted.
• Check the gadget has loaded on the zero.
• Check your modprobe command or configfs script for errors.
• Check the cable.
6.4 The USB Host Cannot Mount The Backing Store
The exact cause will vary but the error return by the mount command may help.
• If the backing store was created with mkfs and has no partition table, try recreating it with a
partition table. See 4.4
• Make sure the correct device node is being used. This must be the one reported by the USB
host.
• Make sure the backing store has been formatted with a file system the OS on the USB host
understands.
• If the backing store has not been initialised, partitioned, and formatted do so using the tools
provided by the USB host30. Be aware that this will destroy all data within the backing
store.
• If the gadget was configured with removable=1, make sure a backing store was also
provide via file=.31
30 Windows users may need to do this in disk management rather than in explorer.
31 Or the equivalents if using configfs
6.5 The USB Host Cannot Write To The Backing Store
In order for the USB host to be able to write to the backing store the following must all be true:
1. The zero’s SD card must not have failed and gone read only.
2. The partition containing a file based backing store must not be mount read only on the zero.
3. A file based backing store must have write permission for the root user.
4. The mass storage gadget must not be configured with ro=y or cdrom=y.
5. The USB host must mount the gadget as read/write.
6.6 Changes Made To The Contents Of The Backing Store
On One Side Are Not Visible On The Other
This expected and normal behaviour. It is also not recommended. See 3.4
Unmount and remount on the side (host or zero) that cannot see the changes. Any pending changes
in the other side’s write cache will still not be visible.
To be sure that all changes have been written and that no changes will be made behind the back of
the reading side, unmount the writing side before (re)mounting on the reading side. This must be
done manually, neither side has any way to force the other to unmount.
7 Advanced Usage
32 One that fully supports linux owner, group, permissions and attributes e.g ext4.
33 This prevents accidental deletion.
7.2 Changing The Backing Store On The Fly
While possible, this not really recommended. The zero has no way to know whether the host is in a
suitable state that it is safe to do so nor does it have any way to force the host to unmount the
backing store.
The risks and dangers are the same as those when disconnecting any drive without first unmounting
it.
36 Depending on the size of the SD card and the backing store you may need to move the backing store onto a a
separate drive to carry out this procedure.
37 See man fstab and man mount.
38 Sync disables read and write caching on the partition thus reducing chance of data being lost if power is suddenly
removed.