USB Gadget Mode on Raspberry Pi: Emulating a Keyboard, Network Adapter, or USB Drive from a Pi Zero
The Raspberry Pi Zero, Zero 2 W, and Pi 4/5 (via their USB-C port) all support USB gadget mode — a Linux kernel feature that lets the Pi's USB port act as a device rather than a host, so when you plug it into a laptop, the laptop sees a keyboard, a network adapter, a USB drive, or several of those at once, instead of a generic peripheral. This is the same underlying capability that makes BadUSB-style attacks possible on the Flipper Zero and Raspberry Pi Pico projects covered elsewhere on this site, but it's a distinct mechanism worth understanding on its own — it runs through the Linux USB gadget subsystem rather than a microcontroller's USB stack, which opens up combinations (simultaneous network + storage + HID) that aren't practical on a bare microcontroller.
Hardware Requirements
BoardGadget Mode SupportPort to Use Pi Zero / Zero W / Zero 2 WFull support via dwc2 overlayThe "USB" port (not "PWR"), the one closest to the middle of the board Pi 4 / Pi 5Supported via the USB-C power port with the right overlayUSB-C port (shared with power — see note below) Pi 3 and earlier (full-size)Not supported — these use a USB host-only controllerN/AOn a Pi 4/5, enabling gadget mode on the USB-C port means it's simultaneously your power input and your gadget data connection when plugged into a host — this works fine for most gadget applications but means you can't easily use a second cable for power once gadget mode is active on that port.
Enabling Gadget Mode
- Edit /boot/config.txt (or /boot/firmware/config.txt on newer Raspberry Pi OS releases) and add: dtoverlay=dwc2
- Edit /boot/cmdline.txt and insert modules-load=dwc2,g_ether right after rootwait (use g_ether for network gadget mode — swap to g_hid or g_mass_storage depending on which gadget type you're setting up, or load multiple as a composite gadget).
- Reboot with the Pi connected via its USB (not power-only) port to a host computer.
- Verify from the host: a network gadget appears as a new USB Ethernet adapter; an HID gadget appears as a generic USB keyboard/mouse; a mass storage gadget mounts as a removable drive.
Network Gadget Mode (g_ether)
This is the most commonly used gadget mode — it turns the Pi into a USB Ethernet device, letting you SSH into a headless Pi Zero over a single USB cable with no separate network setup, no monitor, and no keyboard. On the host side, the new USB network interface typically needs a static IP or gets one via the Pi acting as a DHCP server on that link. This is the mechanism behind many "USB gadget" headless Pi Zero tutorials for driving OctoPrint or Klipper hosts from a laptop with a single cable — genuinely convenient for bench debugging where WiFi isn't reliable or available.
HID Gadget Mode (g_hid) — Keyboard/Mouse Emulation
With the HID gadget loaded, the Pi presents itself as a standard USB keyboard (and optionally mouse) to whatever host it's plugged into. Combined with a Python script reading from /dev/hidg0 and writing raw HID keyboard reports, this is functionally the same category of tool as a Flipper Zero's BadUSB app or a Raspberry Pi Pico BadUSB build — the Pi types out a scripted payload the instant it's plugged in, no user interaction required on the target machine.
This is genuinely useful for legitimate automation — a kiosk that needs to "type" a login sequence, a testing rig that needs to simulate keyboard input for QA — and is exactly as capable of misuse as any other HID injection tool. Only use this against systems you own or have explicit written authorization to test, the same standard that applies to every security-testing topic covered on this site.
Mass Storage Gadget Mode (g_mass_storage)
Presents a backing file or block device on the Pi's SD card as a mountable USB drive to the host. Useful for things like presenting a pre-built disk image to a target machine, or building a "USB drive" that also secretly runs other gadget functions simultaneously via a composite gadget config.
Composite Gadgets: Combining Multiple Functions
The Linux gadget subsystem (via configfs, the more flexible modern approach vs. the older module-parameter method shown above) lets you present several gadget functions over one USB connection at once — network, HID, and mass storage simultaneously, all appearing as a single composite USB device to the host. This is set up by creating a gadget configuration directory structure under /sys/kernel/config/usb_gadget/ — see the kernel’s own configfs gadget documentation for the full attribute reference — and is the approach used by most serious USB gadget mode tutorials once you move past a single function. It requires more setup than the config.txt/cmdline.txt method but is far more flexible and is the standard approach for anything beyond a single-purpose gadget.
Troubleshooting
SymptomCauseFix Host doesn't detect any gadget deviceWrong USB port used (power-only port on Zero, or gadget mode overlay not loaded)Confirm correct port; check dmesg on the Pi for dwc2 driver load errors Network gadget appears but no connectivityNo IP assigned on either end, or DHCP not running on the Pi sideSet a static IP on both host and Pi interface, or run dnsmasq on the Pi HID gadget doesn't type anythingIncorrect HID report descriptor or permissions issue writing to /dev/hidg0Verify report descriptor matches a standard boot keyboard; run script with appropriate permissions Pi won't boot after editing config.txtSyntax error in config.txt or cmdline.txt (cmdline.txt is extremely picky about single-line format)Remove SD card, edit from another machine, verify cmdline.txt is a single line with no line breaksSafety and Ethics Notes
HID gadget mode is a legitimate automation and testing tool, but it is mechanically identical to the "attack" use case — a Pi Zero configured for HID injection plugged into an unattended machine will type whatever payload it's loaded with, unauthenticated and unannounced. Treat any HID or composite gadget build the same way this site treats Flipper Zero BadUSB content: only test against hardware and accounts you own or are explicitly authorized to test, and don't leave a configured gadget device lying around where someone could plug it into a machine you don't have permission to touch.
Wrapping Up
USB gadget mode turns a $15 Pi Zero into a surprisingly capable USB peripheral emulator — a single-cable headless network link for bench work, a scripted HID automation tool, or a composite device combining several functions at once. It's a different mechanism from the Flipper Zero or Pico BadUSB projects covered elsewhere on this site, running through the full Linux gadget subsystem rather than a microcontroller USB stack, which is what makes the composite multi-function setups possible in the first place.