James,
Sorry about the length but here's my additional comments. Page numbers as the document's footer.
Page 3
Tip box: Doesn't mention Bluetooth as possible ways to connect keyboard and mouse or UART/serial as possible way to login.
"First, we need to tell the USB system to use the DWC2 driver, which will enable OTG mode. Edit /boot/firmware/config.txt and add the following:": Add to where in config.txt? What about prefixing with the [all] filter?
"g_mass_storage Exposes an image file as a flash drive": Can also expose a partition or entire drive. Or pretty much any block device. Secondly it's not really as a "flash drive" it's as a USB mass storage device like a flash drive, external HDD/SSD, or ODD.
Page 4
"dtoverlay=dwc2,dr_mode=peripheral": ,dr_mode=peripheral is not strictly necessary as that's the default due to the hardware. It should be harmless though.
"Note" box under "Steps": Yeah the OTG ID pin/line isn't present but from what I've seen it's left floating so defaults to device/peripheral mode.
Page 5
"Raspberry Pi A, B, B+, 2B, 3B, 3B+
The USB ports on these models are connected through a hub chip (LAN9512/LAN9514 or VIA Labs), which strips away OTG
capabilities. They can only operate as USB hosts, so no OTG support is available.":There is no hub chip on A[+] models. They can act as USB devices/peripherals but ",dr_mode=peripheral" is required as the ID pin/line is pulled low which sets host mode. AIUI the possible exception is the 3A+ which must not have the OTP set to allow booting from USB devices as that does block use as a peripheral.
"Mass storage device": The host sees a raw drive so you should really initialise, partition and format it not just create the image and format it. Things get interesting when using a partition (because the host expects a partition table but Linux doesn't) so it's often better to do the partition and format from the USB host.
"removable=1" is not mandatory. It's only required if you want the gadget to present to the host as a drive with removable media e.g. an FDD or card reader.
"You can examine the contents of the backing store": Needs a note about the dangers of having the backing store mounted and writeable from both host and Pi at the same time. You will corrupt your data doing this.
With a partitioned backing store (whether a real partition or an image file) I tend to use the following process for mounting:Where X is the number of the loop device and N is the partition number.
I've not tried mount -o loop with a partitioned image but I'd expect that not to work as you might expect (the loop device will start with the partition table etc not with the first partition's data).
To unmount:
"Ethernet devices": probably needs something about the very annoying habit Windows has of identifying the ethernet gadget as a COM port and how to fix that. Unfortunately all the old ways I know about no longer work. Also applies to the ethernet gadget when setup via configfs.
Page 7
"dtoverlay=dwc" should be "dtoverlay=dwc2". Also need to specify dr_mode for some models.
My experience with RPiOS is that it is not necessary to add dwc2 to /etc/modules. And if it were you'd need to have done so in the Legacy section too. You should probably add libcomposite though.
Page 8
"echo 120 > configs/c.1/Maxpower": might want to increase that for some models. If the USB host does limit you to that value you'll have trouble running anything other than a zero or 1A[+]
"Ethernet (RNDIS and ECM)" same points as above.
"Mass storage": same comments as above regarding the backing store.
Page 10
I'd use /etc/systemd/system and not /lib/systemd/system. AIUI the latter is for services installed by packages and the former overrides the latter. Plus if an update (or package install) creates a service with the same name you may lose a custom service in the latter
Page 12
"Quick reference table": this is wrong in that it indicates that A series Pi models do not support OTG. They can (see above). Also doesn't mention A+, B+, 3A+, CM3+, CM4S, and CM0.
General:
No mention that only one g_* module can be loaded/active at a time.
May want to say something about random MAC addresses and the ethernet gadget. Unless explicitly set manually a new set of random MAC addresses are used each time the gadget is loaded/configured. This creates problems with DHCP assigned addresses or anything else that depends on MAC addresses not changing.
Pi4 (and possibly CM4) users must not have an active "otg_mode=1" line in their config.txt. If they do that always takes precedence over dr_overlay=dwc2. At least that's my experience. The default RPiOS config.txt has a conditional filter that sets otg_mode=1 on CM4
No mention that zero series can hot swap between host and peripheral roles when a dr_mode has not been forced.
Sorry about the length but here's my additional comments. Page numbers as the document's footer.
Page 3
Tip box: Doesn't mention Bluetooth as possible ways to connect keyboard and mouse or UART/serial as possible way to login.
"First, we need to tell the USB system to use the DWC2 driver, which will enable OTG mode. Edit /boot/firmware/config.txt and add the following:": Add to where in config.txt? What about prefixing with the [all] filter?
"g_mass_storage Exposes an image file as a flash drive": Can also expose a partition or entire drive. Or pretty much any block device. Secondly it's not really as a "flash drive" it's as a USB mass storage device like a flash drive, external HDD/SSD, or ODD.
Page 4
"dtoverlay=dwc2,dr_mode=peripheral": ,dr_mode=peripheral is not strictly necessary as that's the default due to the hardware. It should be harmless though.
"Note" box under "Steps": Yeah the OTG ID pin/line isn't present but from what I've seen it's left floating so defaults to device/peripheral mode.
Page 5
"Raspberry Pi A, B, B+, 2B, 3B, 3B+
The USB ports on these models are connected through a hub chip (LAN9512/LAN9514 or VIA Labs), which strips away OTG
capabilities. They can only operate as USB hosts, so no OTG support is available.":There is no hub chip on A[+] models. They can act as USB devices/peripherals but ",dr_mode=peripheral" is required as the ID pin/line is pulled low which sets host mode. AIUI the possible exception is the 3A+ which must not have the OTP set to allow booting from USB devices as that does block use as a peripheral.
"Mass storage device": The host sees a raw drive so you should really initialise, partition and format it not just create the image and format it. Things get interesting when using a partition (because the host expects a partition table but Linux doesn't) so it's often better to do the partition and format from the USB host.
"removable=1" is not mandatory. It's only required if you want the gadget to present to the host as a drive with removable media e.g. an FDD or card reader.
"You can examine the contents of the backing store": Needs a note about the dangers of having the backing store mounted and writeable from both host and Pi at the same time. You will corrupt your data doing this.
With a partitioned backing store (whether a real partition or an image file) I tend to use the following process for mounting:
Code:
sudo losetup --show -fP /path/to/backing-storesudo mount /dev//loopXpN /mountpointI've not tried mount -o loop with a partitioned image but I'd expect that not to work as you might expect (the loop device will start with the partition table etc not with the first partition's data).
To unmount:
Code:
sudo umount /mountpointsudo losetup -d /path/to/backing-store"Ethernet devices": probably needs something about the very annoying habit Windows has of identifying the ethernet gadget as a COM port and how to fix that. Unfortunately all the old ways I know about no longer work. Also applies to the ethernet gadget when setup via configfs.
Page 7
"dtoverlay=dwc" should be "dtoverlay=dwc2". Also need to specify dr_mode for some models.
My experience with RPiOS is that it is not necessary to add dwc2 to /etc/modules. And if it were you'd need to have done so in the Legacy section too. You should probably add libcomposite though.
Page 8
"echo 120 > configs/c.1/Maxpower": might want to increase that for some models. If the USB host does limit you to that value you'll have trouble running anything other than a zero or 1A[+]
"Ethernet (RNDIS and ECM)" same points as above.
"Mass storage": same comments as above regarding the backing store.
Page 10
I'd use /etc/systemd/system and not /lib/systemd/system. AIUI the latter is for services installed by packages and the former overrides the latter. Plus if an update (or package install) creates a service with the same name you may lose a custom service in the latter
Page 12
"Quick reference table": this is wrong in that it indicates that A series Pi models do not support OTG. They can (see above). Also doesn't mention A+, B+, 3A+, CM3+, CM4S, and CM0.
General:
No mention that only one g_* module can be loaded/active at a time.
May want to say something about random MAC addresses and the ethernet gadget. Unless explicitly set manually a new set of random MAC addresses are used each time the gadget is loaded/configured. This creates problems with DHCP assigned addresses or anything else that depends on MAC addresses not changing.
Pi4 (and possibly CM4) users must not have an active "otg_mode=1" line in their config.txt. If they do that always takes precedence over dr_overlay=dwc2. At least that's my experience. The default RPiOS config.txt has a conditional filter that sets otg_mode=1 on CM4
No mention that zero series can hot swap between host and peripheral roles when a dr_mode has not been forced.
Statistics: Posted by thagrol — Sat Jan 17, 2026 8:14 pm