Raspberry Pi Zero – Programming over USB! (Part 1)

Part 2 to this post can be found here.

Update 19/05/2016 – The modules are now included in the most recent version of Raspbian and thanks to some digging around in kernel documentation, it is now possible to set the full thing up without a keyboard/mouse/screen! Just need a Windows/Mac/Linux computer!

Update 15/01/2016 – The modules have now been merged into the Raspberry Pi Foundation maintained kernels! So no more need for custom kernels, just need to grab the most recent alpha kernels. Doing this is now far simpler.

Full credit for the initial documentation for this goes to a number of Pi experts from the Raspberry Pi community, see here and here.

An acknowledgement also to Lady Ada of Adafruit who was working on documenting in parallel to myself on Christmas eve. She has taken a different approach which requires a UART serial cable. Her guide can be found here.

What is this?

The Raspberry Pi Zero is a very cool little computer. At £4, is pretty amazing for the price. But one thing many Pi users have wanted to be able to do for a long time is program their Raspberry Pi from another computer, using only a single USB cable!

The Raspberry Pi Zero is able to do this, hardware wise anyway, although a lack of software support was holding up it ever happening. Until now!

So what can it do?

Using the Linux USB Gadget modules, we can get the Pi Zero to emulate a whole host of USB devices including

  • Virtual Serial – So can get a serial connection into the Pi, similar to using the UART pins. You can use Putty (on Windows) or Screen (on Mac and Linux).
  • Virtual Ethernet – You can get your Pi Zero to appear as a USB Ethernet modem. With a little configuration, you can then get full SSH, VNC, FTP etc.
  • Mass storage device – You can get the Pi Zero to appear as a flash drive, allowing you to for example, copy files over and have the Pi run these files (useful for robotics for example)
  • Virtual MIDI – The Pi Zero could appear as a virtual MIDI instrument.
  • Virtual Audio – The Pi Zero could appear as a virtual headphone output or microphone input.
  • Virtual Human Interface Device (HID) – The Pi Zero could appear as a virtual HID, for example a keyboard or mouse. So when you plug it into your computer, it could start typing!

You can also combine a few of the above (up to 3 at a time) using the g_multi module, although Windows and Mac have difficulty handling it then.


Where is this useful? Lets take an example of some Raspberry Pi robots in a classroom. Although you could be using Wifi for each robot, remembering addresses, unreliability with wifi etc all make wifi a bit of a rubbish answer.
With this, the student simply plugs in the robot and perhaps drops their script onto the flash drive that appears. When they unplug it, the robot runs the script, dumping the results of the script back onto the mass storage device, ready to be read when it is plugged in next.

Another example, lets say you don’t have access to a screen to use with your Raspberry Pi Zero, in for example, a school. You could still let your students play with GPIO or Linux by simply using the serial module (with Putty or Screen), or the virtual ethernet module to allow them SSH access.

How to I set it up on my Raspberry Pi?

I have thrown together a guide over on Github Gists, including links to the downloadable precompiled kernels.

59 thoughts on “Raspberry Pi Zero – Programming over USB! (Part 1)”

  1. It’s like opening the last door on an Advent calendar !

    Thanks to all for this Christmas present which will make our favourite nano-computer even more accessible to everyone =o)

    Bravo to all who’ve worked on both the idea and the technical side for PiZero USB OTG use : DaveB, Andrew M, Simon W, LadyAda and of course the RPFoundation for bringing us the Hardware in the first place !

    Joyeux Noël et bonnes fêtes!

  2. This is just fantastic work Andrew – huge potential , I’ve had a go at this, mind you with a limited ‘skillset’. Bearing in mind it’s still Christmas – would it be possible for you to do a walkthrough on setting it up for a Mac ?? Experiencing a few problems connecting – not sure what I’m doing wrong if at all ?? Apple is notoriously difficult to deal with in terms of 3rd party access / setups as it is so ‘locked down’ ;(

  3. It seems as if the last tar.gz-file is the same as the first. I have a Raspberry Pi Model A (and not Zero) and I then need files that are hard-coded to gadget mode, because the OTG-ID-pin is connected to ground, i.e. always host.

  4. I am interested about using the Raspberry Pi as a MIDI instrument with g_midi, but I am struggling to find any sort of documentation on how this could be done. Do you know of any tutorials/guides that could get me started using g_midi?


  5. Cool stuff ! Like David I’m interested in the HID thing. What prevented you from including the g_hid driver in the kernel? Any advice how we could do that ourselves would be appreciated.

  6. The modules and instructions worked perfectly. I am digging the g_ether for my headless configuration of the zero and with DHCP turned on, its perfect. Thanks again, I even have apache loaded on it so I have portable web server.

  7. Thanks for helping me go networking on my pi zero.

    What is the correct set up on pi zero and host linux, what needs to be append to the end of /etc/network/interfaces using address on the pi?

    This seems to work fine for me, but should I be using
    a netmask of and
    pi zero /etc/network/interfaces

    allow-hotplug usb0
    iface usb0 inet static

    My debian linux /etc/network/interfaces

    allow-hotplug usb0
    iface usb0 inet static
    up iptables -A POSTROUTING -t nat -j MASQUERADE -s
    up sysctl -w net.ipv4.ip_forward=1
    up route add -host usb0
    down iptables -D POSTROUTING -t nat -j MASQUERADE -s

    Got some info from

  8. Great guide, I was able to get all the components in the guide to work last night. One thing though, when I tried to modprobe the g_hid driver, it says it is not foumd. Was it not included in the kernel? Would it be possible to compile the driver and modprobe it? Thanks!

    1. Only on the data port. You can only use the power port for power unfortunately, its data lines aren’t connected to anything.

  9. Has anyone managed to get the g_mass_storage module working with the pi a+ model? Is it even possible? Any help or knowledge would be highly appreciated. Thanks!

    1. Unfortunately I am not aware of anyone actually getting it working on A+ yet, or any of the modules for that matter. It looks like there is an issue with the OTG ID pin not being connected. It is still work in progress from what I can gather.

  10. I’m having difficulty setting up usb0 to have a static IP address to connect to. I’m only using the g_ether module.

    I’m using the Raspberry Pi Zero as a LAMP server, with PHP.

    For the laptop, I am using Arch with XFCE. Is there a way I can set a unique address to the Raspberry Pi?

    1. Don’t worry – solved my own issue!

      In XFCE / distros that use nm-connection-editor, you need to make a new Ethernet Interface. Call it whatever you want, and under the “IPv4” tab, for the Method, select “Link-Local Only”.

      It probably automatically created the interface for me, but I must’ve deleted it when I was tinkering with my own network.

      Great guide, by the way! This’ll be extremely useful when developing my PHP scripts!

  11. Followed the g_ether instructions and all ok, the Zero is powered and sat at the prompt after connecting from the USB on the laptop.

    I can’t seem to SSH though – assuming it’s the port number (default 22 not working) – likely I’m missing the obvious (new to a lot of this). Should I be using a different port number?

    Many thanks for a great tutorial!

    1. Just figured out, how to make it work on minibian:

      1) using 1 GB microsd
      2) apt-get update
      3) apt-get install raspi-config
      4) run raspi-config and resize partition
      5) reboot
      6) apt-get install rpi-update
      7) BRANCH=next rpi-update
      8) reboot
      9) add “dtoverlay=dwc2” in /boot/config.txt
      10) add “dwc2” in /etc/modules
      11) add “g_serial” in /etc/modules
      12) reboot
      13) systemctl enable [email protected]
      14) systemctl start [email protected]
      15) edit /etc/securetty and add ttyGS0 at the end
      15) reboot

      Now I can connect my pi zero via microusb cable to PC, Windows 8.1 detected and created ELMO GMAS (COM5) and I can connect via Putty.

  12. Hello,

    i have updated to the new raspbian release of 2016-02-09 and the USB- Gadget isn’t working…can anyone confirm that or hast anyone a solution?


  13. Hello,

    after the new offical raspberry update (2016-02-09), the gadget mode isn´t working! Kernel 4.4.1+

    Can anyone confirm the problem or have anyone a Solution?


  14. Hi, I’m trying to get my new A+ to talk over USB OTG, but can’t seem to get another host to see it as a device using the full size A port, I believe the micro USB port is unconnected apart from the power pins – anybody found this issue?

  15. I’m very interested in using the RPi zero to power a custom game controller. Getting it to behave as a HID sounds ideal.
    Once I have loaded the g_hid driver, how would I send commands to it?

    If I can work that out, then mapping GPIO inputs to g_hid outputs would allow me to construct a controller.

  16. I’m unable to make it work. My computer is running Win 10.
    I’ve followed the g_ether method 2, but it doesn’t show up on windows. On rpi boot, I see:
    [ 4.516265] systemd[1]: systemd-modules-load.service: main process exited, code=exited, status=1/FAILURE
    [ 4.536829] systemd[1]: Failed to start Load Kernel Modules.
    [ 4.544593] systemd[1]: Unit systemd-modules-load.service entered failed state.
    This is after enabling it on a fresh Raspbian, with no issues before enabling it.

  17. i would like to use it as a serial injector in order to be able to distinguish multiples of the same device, keyboard/mouse in my case. can one of the usb ports act as a hid slave while the other is the host for the keyboard/mouse and if so, how would i power the zero? just plug an active hub on the host side? or does it get enough power from the slave port to power itself and the keyboard/mouse? is it possible with this device or is there any other solution or device which would let me add a serial number to a usb device?

    1. The power USB port on the Pi Zero is just that, only for power. You also can’t attach a hub to the Pi Zero and use it in slave mode. If using it in USB slave mode, the only USB device connected to it can be a single computer.
      If is only serial you want, may want to look at doing that over UART over the GPIO pins with a single USB UART adapter.

    Unfortunately, as of November 2016 (Raspbian Jessie), the SSH server is NOT RUNNING ‘out of the box’. The setup works perfectly but the connection is refused. It responds to pings.
    By connecting by some other means and running raspi-config you can easily fix this. I did this and at the same time setup wifi and now connect that way so haven’t been back to a USB connection but I would have thought it should work.

  19. thanks for that article –
    I want to add an ethernet module to the Pi Zero (something like the ENC28J60) to build an USB mass storage, which file system, I could modify through ethernet.

    would anyone have pointer to do this or concern in its feasability?

  20. Could something like this be used to make the PI act as a custom device that talks to a computer provided that I am willing to write a driver for it?

  21. Hi,

    I have been struggling with getting on speaking terms with my PI mod A – that is, one USB, power and HDMI ports. Target of course to be able to PUTTY / SSH it from my pc so I can develop with Netbeans using the A as build host.

    (Doing the same for the Pi 2 was an easy stake, just configure fixed IP address for eth0 and set up the ethernet interface on my pc accordingly.)

    After lots of tweaking (without any progress at all), I found that the simplest solution was to use an USB-to-Ethernet gadget that I happened to have around.

    So: My solution to ssh into the Pi mod A is as follows:
    Build: Latest Rasbian build of November -16
    – In /boot/config.txt: Add dtoverlay=dwc2 somewhere at the bottom to enable the dwc2 overlay
    – in /etc/modules: Add dwc2 on a line of its own to make the Pi use it
    – In /etc/network/interfaces:
    Comment out /delete the line
    iface eth0 inet manual

    Add the following lines to set a static IP for eth0
    # Don’t know if this is neccessary. Doesn’t seem to do any harm, anyway
    allow-hotplug eth0
    # Configure the eth0 as having static IP
    iface eth0 inet static
    # If you have a DHCP router in your network, you better stay with the 169.254.x.x address space. Select freely.
    # I set the default gateway to the IP of the ethernet I/F of my pc
    # Don’t know if these are really neccessary either.

    Reboot, and ping the address from yout PC, which you have connected with an ordinary tp cable to the USB-to-Ethernet gadget

    One peculiarity: This solution worked without enabling dwc2 too, as long as I had the HDMI cable connected to the Pi. When I disconnected it, the Pi responded some ten times to ping, end then the connection died. Enabling dwc2 soplved that problem.

  22. I have a project on the RPi 3 for which this kind of functionality would be extremely useful.

    Would it be possible to set up this kind of functionality for the Pi 3, or is it something specific to the hardware of the Pi 0?

    Please let me know. Thanks!

    1. It is unfortunately only an option for the Pi Zeros, as the full sized Pis (like Pi 3) have the USB LAN hub chip in the way.

Leave a Reply

Your email address will not be published. Required fields are marked *