Raspberry Pi 4 as USB-C Gadget

Hi guys, today I’ll show you a very cool featured introduced with Raspberry Pi 4!

In a previus post I writed about using a Raspberry Pi Zero/Zero W as a USB gadget, This allows them to be powered and accessed via one of the micro USB sockets and it shows up as both a CD-Drive and a ethernet device.

A few days ago a new Raspberry Pi 4 bootloader was released and allows us to use the Pi4’s type-c connection for power, network boot and data sharing! For more information about the bootloader check raspberrypi.org.

Software

As always we need to install the new Raspbian OS, if you don’t know how to do that check my beginner page where I explain how to do that with different OS.

If you have already installed Raspbian Buster you can simple update the bootloader with this command lines:

sudo apt update
sudo apt full-upgrade
sudo apt install rpi-eeprom

Now we need to make a few changes in the config.txt and cmdline.txt files, the configuration is the same used in the Raspberry Pi Zero USB gadget but updated for Raspbian Buster, add this line at the end of config.txt:

dtoverlay=dwc2

and add this at the end of cmdline.txt:

modules-load=dwc2

you can edit directly from SD card or you can use the commands:

sudo nano /boot/config.txt

sudo nano /boot/cmdline.txt

After that we need to add:

  • libcomposite to /etc/modules
  • denyinterfaces usb0 to /etc/dhcpcd.conf

We are ready to configure the network sharing, to do that you need to install and configure dnsmasq

sudo apt install dnsmasq

And create /etc/dnsmasq.d/usb with the following content:

interface=usb0
dhcp-range=10.55.0.2,10.55.0.6,255.255.255.248,1h
dhcp-option=3
leasefile-ro

To create the file you can use the command:

sudo nano /etc/dnsmasq.d/usb

With the same steps you need to create /etc/network/interfaces.d/usb0 with the following content:

auto usb0
allow-hotplug usb0
iface usb0 inet static
  address 10.55.0.1
  netmask 255.255.255.248

And /root/usb.sh, a simple python script with the following lines of code:

#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p pi4
cd pi4
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
echo 0xEF > bDeviceClass
echo 0x02 > bDeviceSubClass
echo 0x01 > bDeviceProtocol
mkdir -p strings/0x409
echo "fedcba9876543211" > strings/0x409/serialnumber
echo "Ben Hardill" > strings/0x409/manufacturer
echo "PI4 USB Device" > 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
# Add functions here
# see gadget configurations below
# End functions
mkdir -p functions/ecm.usb0
HOST="00:dc:c8:f7:75:14" # "HostPC"
SELF="00:dd:dc:eb:6d:a1" # "BadUSB"
echo $HOST > functions/ecm.usb0/host_addr
echo $SELF > functions/ecm.usb0/dev_addr
ln -s functions/ecm.usb0 configs/c.1/
udevadm settle -t 5 || :
ls /sys/class/udc > UDC
ifup usb0
service dnsmasq restart

This script need to be run every time the Raspberry Pi is booted, to do that add /root/usb.sh to /etc/rc.local before exit 0 line.

With this setup the Pi4 will show up as a ethernet device with an IP address of 10.55.0.1 and will assign the device you plug it into an IP address via DHCP. This means you can just ssh to [email protected] to start using it.

Hope you find it usefull and cool!