Project 14: USB Gadget Mode (Device Emulation)

Configure the Pi Zero 2 W to appear as a USB Ethernet device for reliable headless access.

Quick Reference

Attribute Value
Difficulty Advanced
Time Estimate 1–2 weekends
Main Programming Language Bash (Alternatives: Python, Go, Rust)
Alternative Programming Languages Python, Go, Rust
Coolness Level High
Business Potential Medium
Prerequisites Boot configuration, Linux networking
Key Topics USB roles, Linux gadget framework, IP config

1. Learning Objectives

By completing this project, you will:

  1. Enable USB gadget mode on the Pi Zero 2 W.
  2. Configure the Pi to appear as a USB Ethernet device.
  3. Persist gadget configuration across reboots.
  4. Secure the USB interface to prevent unauthorized access.

2. All Theory Needed (Per-Concept Breakdown)

Concept 1: USB Host vs Device and the Linux Gadget Framework

Fundamentals

USB is a host/device protocol: one side is the host (PC), the other is the device (peripheral). The Pi Zero 2 W can act as a USB device via its OTG port, but only if configured to load the correct kernel modules. The Linux gadget framework lets a device emulate different USB functions (Ethernet, serial, storage). This project uses the g_ether or libcomposite gadget to appear as a USB network adapter.

Deep Dive into the concept

USB roles are asymmetric. The host controls enumeration and provides power; the device responds with descriptors describing its capabilities. On Raspberry Pi Zero 2 W, the OTG port can act as device, but you must enable the dwc2 driver and load gadget modules early in boot. This is usually done via config.txt and cmdline.txt or kernel module configuration. If the gadget module loads after boot, the host might not see the device reliably.

The Linux gadget framework provides prebuilt modules (like g_ether for Ethernet over USB) and a more flexible libcomposite framework where you define descriptors and functions manually. For this project, g_ether is simplest: it emulates a USB Ethernet device with an RNDIS (Windows) or CDC ECM (Linux/macOS) interface. Once enumerated, the host sees a new network interface, and you can assign IP addresses to both sides. Typically, the device uses a static IP (e.g., 192.168.7.2) and the host uses another (e.g., 192.168.7.1). You then SSH over that link.

Security is important because USB gadget mode creates a direct network link. You should firewall the interface and allow only SSH. You can also disable services bound to other interfaces. If the Pi is connected to an untrusted host, that host has a direct path into the device. For this project, at minimum disable password SSH and restrict SSH to the USB interface.

Debugging gadget mode includes checking lsmod for gadget modules, verifying dmesg logs, and inspecting lsusb on the host. If enumeration fails, common causes include missing dwc2 overlay, incorrect cmdline.txt module loading, or a power-only USB cable. The Pi Zero 2 W uses a micro-USB OTG port, so the cable must support data.

How this fit on projects

This concept is used in §3 and §5.10 and connects to Project 1 (headless provisioning) as a fallback access method.

Definitions & key terms

  • OTG: On-The-Go, USB port that can be host or device.
  • Gadget: USB device emulation in Linux.
  • RNDIS/CDC: USB Ethernet protocols.
  • Descriptors: USB data that describes device capabilities.

Mental model diagram (ASCII)

Host (laptop) <---- USB ----> Pi Zero 2 W (g_ether)
        IP: 192.168.7.1        IP: 192.168.7.2

How it works (step-by-step, with invariants and failure modes)

  1. Enable dwc2 overlay and load gadget module at boot.
  2. Pi enumerates as USB Ethernet device.
  3. Configure static IP on USB interface.
  4. Connect via SSH over USB.

Failure modes:

  • Power-only cable -> no enumeration.
  • Gadget module not loaded -> device not recognized.
  • No IP assignment -> no connectivity.

Minimal concrete example

# /boot/firmware/config.txt
 dtoverlay=dwc2
# /boot/firmware/cmdline.txt
 modules-load=dwc2,g_ether

Common misconceptions

  • “Any micro-USB cable works.” Many are power-only.
  • “USB gadget is always enabled.” It requires explicit configuration.

Check-your-understanding questions

  1. Who provides power in a USB connection?
  2. What does g_ether emulate?
  3. Why must modules load at boot for gadget mode?

Check-your-understanding answers

  1. The host provides power.
  2. A USB Ethernet device (RNDIS/CDC).
  3. Enumeration happens at boot; late loading may miss it.

Real-world applications

  • Headless device provisioning, USB-debug access, embedded products.

Where you’ll apply it

  • This project: §3.2, §5.10.
  • Other projects: Project 1.

References

  • Linux USB gadget documentation
  • Raspberry Pi docs on USB gadget mode

Key insights

USB gadget mode turns the Pi into a device, not a host; your boot config makes or breaks it.

Summary

Gadget mode is a powerful fallback for headless access, but requires correct boot-time configuration.

Homework/Exercises to practice the concept

  1. Enumerate the gadget on a Linux host and inspect descriptors.
  2. Test with a known data-capable cable.
  3. Bind SSH only to the USB interface.

Solutions to the homework/exercises

  1. Use lsusb -v to inspect descriptors.
  2. Data-capable cable shows a new network interface.
  3. Configure sshd to listen on usb0 only.

3. Project Specification

3.1 What You Will Build

A USB gadget configuration that makes the Pi appear as a USB Ethernet device for SSH access.

3.2 Functional Requirements

  1. Enable gadget mode via boot config.
  2. Configure static IP on USB interface.
  3. Allow SSH over USB.
  4. Persist across reboots.

3.3 Non-Functional Requirements

  • Performance: USB link established within 10 seconds.
  • Reliability: Enumeration works on Linux/macOS.
  • Usability: Single command to verify status.

3.4 Example Usage / Output

$ ./usb_gadget_status
USB gadget mode: enabled
Host link: up
Device IP: 192.168.7.2

3.5 Data Formats / Schemas / Protocols

Status JSON:

{"usb_gadget":true,"host_link":"up","ip":"192.168.7.2"}

3.6 Edge Cases

  • Host OS lacks RNDIS support.
  • Gadget module not loaded at boot.
  • USB cable missing data lines.

3.7 Real World Outcome

The Pi appears as a USB network adapter and is reachable via SSH without Wi-Fi.

3.7.1 How to Run (Copy/Paste)

bash enable_gadget.sh

3.7.2 Golden Path Demo (Deterministic)

export FIXED_TIME="2026-01-01T13:00:00Z"
bash enable_gadget.sh --simulate

Expected output:

[2026-01-01T13:00:00Z] gadget=enabled usb0=192.168.7.2

3.7.3 Failure Demo (Deterministic)

bash enable_gadget.sh --simulate --cable=power-only

Expected output:

[ERROR] No USB enumeration detected

Exit code: 141

3.7.4 CLI Exit Codes

  • 0: Success
  • 140: Gadget module load failure
  • 141: Enumeration failure

4. Solution Architecture

4.1 High-Level Design

Boot Config -> Gadget Module -> USB Enumeration -> IP Config -> SSH

4.2 Key Components

| Component | Responsibility | Key Decisions | |—|—|—| | Boot Config | Load dwc2 and gadget | Early load | | Gadget Module | Create USB Ethernet | g_ether vs libcomposite | | Network Config | Assign IP | Static vs DHCP | | Security | Limit access | SSH only |

4.3 Data Structures (No Full Code)

USB_IP=192.168.7.2

4.4 Algorithm Overview

Key Algorithm: Gadget Setup

  1. Add overlay and module load.
  2. Configure interface IP.
  3. Verify link and SSH.

Complexity Analysis:

  • Time: O(1)
  • Space: O(1)

5. Implementation Guide

5.1 Development Environment Setup

sudo apt-get install -y usbutils

5.2 Project Structure

project-root/
├── enable_gadget.sh
├── usb0.conf
└── README.md

5.3 The Core Question You’re Answering

“How can a Linux system emulate a USB device instead of a host?”

5.4 Concepts You Must Understand First

  1. USB device vs host roles.
  2. Gadget framework and modules.
  3. Network interface configuration.

5.5 Questions to Guide Your Design

  1. How will you persist gadget mode across reboots?
  2. How will you secure USB access?

5.6 Thinking Exercise

Draw the USB host/device relationship and identify who provides power.

5.7 The Interview Questions They’ll Ask

  1. What is USB gadget mode?
  2. Why is it useful for headless devices?
  3. How do you debug enumeration failures?

5.8 Hints in Layers

Hint 1: Check for dwc2 overlay in config.txt.

Hint 2: Load g_ether and check lsmod.

Hint 3: Assign static IP on usb0.

5.9 Books That Will Help

| Topic | Book | Chapter | |—|—|—| | Kernel modules | Linux Kernel Development | Ch. 4 | | Networking | Computer Networks | Ch. 2 |

5.10 Implementation Phases

Phase 1: Boot config (2 hours)

  • Enable dwc2 overlay and module loading.

Phase 2: Network (3 hours)

  • Assign IP and test connectivity.

Phase 3: Security (2 hours)

  • Restrict SSH and firewall USB interface.

5.11 Key Implementation Decisions

| Decision | Options | Recommendation | Rationale | |—|—|—|—| | Gadget module | g_ether / libcomposite | g_ether | Simpler setup | | IP config | Static / DHCP | Static | Deterministic |


6. Testing Strategy

6.1 Test Categories

| Category | Purpose | Examples | |—|—|—| | Unit Tests | Script checks | Config file validation | | Integration Tests | Enumeration | lsusb on host | | Edge Case Tests | Power-only cable | Enumeration failure |

6.2 Critical Test Cases

  1. USB interface appears on host.
  2. SSH over USB works.
  3. Power-only cable -> exit 141.

6.3 Test Data

USB IP: 192.168.7.2

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

| Pitfall | Symptom | Solution | |—|—|—| | Power-only cable | No interface | Use data cable | | Missing overlay | No gadget | Add dwc2 | | No IP | No connectivity | Configure usb0 |

7.2 Debugging Strategies

  • Check dmesg on Pi and host.
  • Use lsusb to verify enumeration.

7.3 Performance Traps

  • High USB traffic can impact CPU; keep services minimal.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add USB serial gadget (CDC ACM).

8.2 Intermediate Extensions

  • Add composite gadget (Ethernet + serial).

8.3 Advanced Extensions

  • Implement custom USB descriptors with libcomposite.

9. Real-World Connections

9.1 Industry Applications

  • Headless provisioning and field service.
  • Linux USB gadget examples.

9.3 Interview Relevance

  • USB roles and gadget frameworks are common embedded topics.

10. Resources

10.1 Essential Reading

  • Linux USB gadget documentation.

10.2 Video Resources

  • USB gadget setup tutorials.

10.3 Tools & Documentation

  • lsusb, dmesg, BlueZ docs.

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain USB host vs device roles.
  • I can explain how gadget modules load at boot.

11.2 Implementation

  • USB Ethernet is working.
  • SSH over USB is secured.

11.3 Growth

  • I can discuss gadget mode in interviews.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Pi appears as USB Ethernet device.

Full Completion:

  • SSH over USB with persistent config.

Excellence (Going Above & Beyond):

  • Composite USB gadget with multiple functions.