Connecting USB devices to WSL

Ben McMorran

I’m a software engineer building tooling for Visual Studio and Visual Studio Code to support C++ embedded device development. These physical devices typically connect to a computer over USB, but we discovered we couldn’t use WSL to test our tools on Linux because it does not support USB. We weren’t alone — support for connecting physical USB devices to WSL is highly requested by the community as well.

While this functionality is still not natively available in WSL, I’m excited to announce that our summer intern, Nelson Daniel Troncoso Aldas, contributed changes to the open-source usbipd-win project to enable common developer USB scenarios like flashing an Arduino or accessing a smartcard reader.

Setup

To get started with this functionality, first ensure you’re running Windows 11 and have installed all WSL updates. Running uname -a from within WSL should report a kernel version of 5.10.60.1 or later. You’ll need to be running a WSL 2 distro.

Install the latest release of usbipd-win.

From within WSL, install the user space tools for USB/IP and a database of USB hardware identifiers. The instructions below are for Ubuntu — other distributions may require a different usbip client package. On Ubuntu 20.04 LTS, run these commands:

sudo apt install linux-tools-5.4.0-77-generic hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/5.4.0-77-generic/usbip 20

At this point a service is running on Windows to share USB devices, and the necessary tools are installed in WSL to attach to shared devices.

Attaching a device

First ensure a WSL command prompt is open. This will keep the WSL 2 lightweight VM active.

From an administrator command prompt on Windows, run this command. It will list all the USB devices connected to Windows.

usbipd wsl list

Select the bus ID of the device you’d like to attach to WSL and run this command. You’ll be prompted by WSL for a password to run a sudo command.

usbipd wsl attach --busid <busid>

From within WSL, run lsusb to list the attached USB devices. You should see the device you just attached and be able to interact with it using normal Linux tools. Note that depending on your application, you may need to configure udev rules to allow non-root users to access the device.

Once you are done using the device in WSL, you can either physically disconnect the device or run this command from an administrator command prompt on Windows.

usbipd wsl detach --busid <busid>

How it works

This functionality takes advantage of the USB/IP protocol to forward USB traffic over the virtual network interface between Windows and WSL. Code for USB/IP support has existed in the Linux kernel since 2009, but several recent changes made it easier to use in WSL.

  • We updated the configuration options for the WSL Linux kernel to enable USB/IP support. This simplifies setup in WSL and avoids requiring users to build the kernel themselves.
  • While support for attaching devices over USB/IP exists in Linux (a client), there was no corresponding server support for USB/IP in Windows. usbipd-win fills this gap. We contributed a command line interface to the project to both enable a USB device for sharing on Windows and attach it from within WSL.

We’d also like to give a shoutout to Frans van Dorsselaer, a system architect from the Netherlands who started usbipd-win. In his own words:

This started as a personal hobby project to get a single device working. I recently switched from VirtualBox to Hyper-V, but I was missing the USB passthrough functionality for my device. Unhappy with the existing solutions, either expensive commercial solutions or open-source projects that required unsigned drivers, I decided that I could do this! I read up on the USB standard, the USBIP implementation in the Linux kernel, and the VirtualBox driver source code. Next, a colleague of mine asked if his USB token would work too. Of course, it didn’t, but I decided to publish the project on GitHub and make it feature complete. Microsoft found my project and decided to help make it more mature with a proper management interface and support for WSL. And that is where we are now: configurable USB passthrough for Hyper-V and WSL.

Where to give feedback

We’re excited for you to try connecting USB devices to WSL. If you have feedback for this project, please open an issue on the open-source usbipd-win project. Learn more about WSL, including how to set up common development tools like Git, VS Code, Docker containers, databases, GPU acceleration for machine learning, and more, by visiting the WSL documentation. Finally, be on the lookout for future announcements from the C++ embedded development team about tooling to improve the embedded development experience regardless of device or compiler. Happy coding!

10 comments

Discussion is closed. Login to edit/delete existing comments.

  • Mickey Cohen 1
    1. Why is Windows 11 insider version needed? I ave Windows 10 and I have rebuilt the kernel of 18.04 to support usbip.
    2. Tests with usbip between my windows 10 host and wsl2 vm caused, at some point, disappearance of the usb webcams I was using. I had to go back to a restore point. “usbip unbind” would not release what it did not bin in this session.
    3. There could be a usbip bug that prevents sharing of wencams in 18.04. Virtualhere product that relies on usbip – fails with webcams because of it. (Flexihug works pefect but it price tag is not for martals like myself).
    4. Test of usbip over Windows11 insider and Ubuntu 18.04 fail due to the same bug. Did you test the above with 20.04 (I think that webcams work with it, https://zenn-dev.translate.goog/pinto0309/articles/0723ae46501beb?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=iw&_x_tr_pto=nui ) or 18.04 (I am sure webcams do not work with it https://www.virtualhere.com/content/wsl2-client-execution-fails-vhci-hcd-not-found ) ?
  • Kota Uchida 1

    In my case, I have to restart my WSL2 instance before attaching a device.
    Before restarting, the attach command failed as following:

    >usbipd wsl attach --busid 6-3
    [sudo] password for uchan:
    libusbip: error: udev_device_new_from_subsystem_sysname failed
    usbip: error: open vhci_driver
    usbipd: error: Failed to attach device with ID '6-3'.

    Then I run “wsl –shutdown” in a command prompt on Windows, and re-open WSL2 terminal to start Linux.
    Now I can attach an USB device as this blog post says.

    • anonymous 1

      this comment has been deleted.

    • Ricky Gonce 1

      Try updating WSL. For me, this issue was caused by a version mismatch.
      In Windows:

      wsl --update

      then, as the output says, restart WSL for the changes to take effect.

      wsl --shutdown
  • john ormonde 1

    I’m trying to understand what WSL and usbip are doing:
    wsl diskdrive list brief reports my USB thumbdrive as \.\PHYSICALDRIVE2 and my internal SSD as \.\PHYSICALDRIVE0

    but in regedit the DeviceName for my internal SSD is PhysicalDrive2 (HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\ Scsi Bus 0\Target ID 0\Logical Unit Id 0)

    any idea why the discrepancy ?

  • Eric-Olivier Perrin 1

    I’ve attached a USB Stick (mass storage 64Gb crypted Luks) to WSL (debian 10 embedded).

    ‘udevadm monitor’ saw the USB device attachment:
    KERNEL[3418.705250] add /devices/platform/vhci_hcd.0/usb1/1-1 (usb)
    KERNEL[3418.707326] add /devices/platform/vhci_hcd.0/usb1/1-1/1-1:1.0 (usb)
    KERNEL[3418.707799] bind /devices/platform/vhci_hcd.0/usb1/1-1 (usb)

    lsusb ok:

    lsusb

    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 002: ID 090c:1000 Silicon Motion, Inc. – Taiwan (formerly Feiya Technology Corp.) Flash Drive
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    But lsblk didn’t see the block device corresponding to the USB stick and no /dev/sdX has been added.
    So I can not access to the USB device and decrypt it. 🙁

    I have checked WSL2 kernel config in https://github.com/microsoft/WSL2-Linux-Kernel/blob/master/Microsoft/config-wsl
    and I discovered with stupor “# CONFIG_USB_SUPPORT is not set” and also “USB Mass Storage Support” is not activated.

    We have to activate this config, compile kernel and install it before attaching USB flash disk or memory stick (ex : https://github.com/jovton/USB-Storage-on-WSL2)

  • Gheorghe Marinca 1

    This also works on Win10, but as of today the WSL update that includes the mentioned linux kernel is not available in Windows Update for Win10 (home edition in my case). You just need to go to https://www.catalog.update.microsoft.com/Search.aspx?q=wsl and pick the 5.10.60.1 update

    • Udi Finkelstein 1

      Thanks! It works!

  • Burak Kizilkaya 1

    How I can access the serial port without root access?

    I tried with this command:

    screen /dev/ttyUSB0

    and didn’t work. If I paste this command:

    sudo screen /dev/ttyUSB0

    then it works.

    I added my user to the group dialout but this didn’t work.

  • Paxsali Akler 1

    Hi all,

    you can automate the process of finding out the latest linux-tools-*-generic version for your currently running kernel:

    #!/usr/bin/env bash
    
    rel="$(uname -r)"
    rel="${rel%%-*}"
    rel=(${rel//./ })
    
    function latest_linux_tools {
        apt-cache search linux-tools |
        awk -v cur_ver="${rel[*]}" '
        /^linux-tools([-\.][0-9]+)+-generic\>/ {
            ltg_package=$1
            gsub(/[^0-9]+/," ",$1);
            gsub(/^\s*/,"",$1);
            split($1,ltg_ver,/\s*/);
            split(cur_ver,cmp_ver,/\s*/)
            if (ltg_ver[1]<=cmp_ver[1] && ltg_ver[2]<=cmp_ver[2] && ltg_ver[3]<=cmp_ver[3]) {
                print ltg_package;
            }
        }' | sort -nr | head -n 1
    }
    
    # optional ...
    apt-get install "$@" "$(latest_linux_tools)"
    

    Use it like this:

    vi /usr/local/bin/install_linux_tools_generic
    # Copy & Paste above snippet into the file...
    chmod u+x /usr/local/bin/install_linux_tools_generic
    
    # preview installation
    install_linux_tools_generic -s
    
    # check, if OK, perform the installation
    install_linux_tools_generic -y
    

    Have fun.

Feedback usabilla icon