└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Adding USB support to WSL 2 2 | 3 | This method adds support to WSL 2 by using USBIP on Windows to forward USB packets to USBIP on Linux. 4 | The Linux kernel on WSL 2 does not support USB devices by default. The instructions here will explain how to add USB functionality to the WSL Linux kernel and how to use USBIP to hook devices into Linux. 5 | 6 | ## USBIP-Win 7 | 8 | If you require the latest version of usbip-win you'll have to build usbip-win yourself. 9 | 10 | Install git for Windows if you haven't already: 11 | > https://gitforwindows.org/ 12 | 13 | 14 | Open git bash in the start menu and clone usbip-win: 15 | ``` 16 | $ git clone https://github.com/cezuni/usbip-win.git 17 | ``` 18 | 19 | Follow the instructions to build usbip-win in README.md. You'll have to install Visual Studio (community and other SKU's work), the Windows SDK and the Windows Driver Kit. Install each one in the order that is given in the instructions and don't install more then 1 thing at a time or the Windows SDK or Windows Driver Kit will install in a broken state that took me hours to figure out. 20 | 21 | If you don't need the latest version you can get prebuilt versions located here: 22 | > https://github.com/cezuni/usbip-win/releases 23 | 24 | ## Adding USB support to WSL Linux 25 | 26 | Install WSL 2: 27 | > https://docs.microsoft.com/en-us/windows/wsl/wsl2-install 28 | 29 | Please take note that you must be running Windows 10 build 18917 or higher as explained in the description. 30 | 31 | You'll need Windows update to function to update to this version. 32 | 33 | If Windows update doesn't work because of various policy restrictions at your work, you can fix this by going into regedit.exe and locating to: 34 | > HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate 35 | 36 | and deleting all entries. This will probably auto-refresh in the future with the original settings when you log back onto your domain. I think changing these settings are not good anyway so I won't miss the changes. 37 | 38 | Open Ubuntu in WSL by navigating to the start menu and opening Ubuntu 39 | 40 | Update sources: 41 | ``` 42 | ~$ sudo apt update 43 | ``` 44 | 45 | Install prerequisites to build Linux kernel: 46 | ``` 47 | ~$ sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev autoconf libudev-dev libtool 48 | ```` 49 | 50 | Find out the name of your Linux kernel: 51 | ``` 52 | ~$ uname -r 53 | 4.19.43-microsoft-standard 54 | ``` 55 | 56 | Clone the WSL 2 kernel. Typically kernel source is put in /usr/src/[kernel name]: 57 | ``` 58 | ~$ sudo git clone https://github.com/microsoft/WSL2-Linux-Kernel.git /usr/src/4.19.43-microsoft-standard 59 | ~$ cd /usr/src/4.19.43-microsoft-standard 60 | ``` 61 | 62 | Checkout your version of the kernel: 63 | ``` 64 | /usr/src/4.19.43-microsoft-standard$ sudo git checkout v4.19.43 65 | ``` 66 | 67 | Copy in your current kernel configuration: 68 | ``` 69 | /usr/src/4.19.43-microsoft-standard$ sudo cp /proc/config.gz config.gz 70 | /usr/src/4.19.43-microsoft-standard$ sudo gunzip config.gz 71 | /usr/src/4.19.43-microsoft-standard$ sudo mv config .config 72 | ``` 73 | 74 | Run menuconfig to select what kernel modules you'd like to add: 75 | ``` 76 | /usr/src/4.19.43-microsoft-standard$ sudo make menuconfig 77 | ``` 78 | 79 | Navigate in menuconfig to select the USB kernel modules you'd like. These suited my needs but add more or less as you see fit: 80 | ``` 81 | Device Drivers->USB support[*] 82 | Device Drivers->USB support->Support for Host-side USB[M] 83 | Device Drivers->USB support->Enable USB persist by default[*] 84 | Device Drivers->USB support->USB Modem (CDC ACM) support[M] 85 | Device Drivers->USB support->USB Mass Storage support[M] 86 | Device Drivers->USB support->USB/IP support[M] 87 | Device Drivers->USB support->VHCI hcd[M] 88 | Device Drivers->USB support->VHCI hcd->Number of ports per USB/IP virtual host controller(8) 89 | Device Drivers->USB support->Number of USB/IP virtual host controllers(1) 90 | Device Drivers->USB support->USB Serial Converter support[M] 91 | Device Drivers->USB support->USB Serial Converter support->USB FTDI Single Port Serial Driver[M] 92 | Device Drivers->USB support->USB Physical Layer drivers->NOP USB Transceiver Driver[M] 93 | Device Drivers->Network device support->USB Network Adapters[M] 94 | Device Drivers->Network device support->USB Network Adapters->[Deselect everything you don't care about] 95 | Device Drivers->Network device support->USB Network Adapters->Multi-purpose USB Networking Framework[M] 96 | Device Drivers->Network device support->USB Network Adapters->CDC Ethernet support (smart devices such as cable modems)[M] 97 | Device Drivers->Network device support->USB Network Adapters->Multi-purpose USB Networking Framework->Host for RNDIS and ActiveSync devices[M] 98 | ``` 99 | 100 | Build the kernel and modules with as many cores as you have available (-j [number of cores]). This may take a few minutes depending how fast your machine is: 101 | ``` 102 | /usr/src/4.19.43-microsoft-standard$ sudo make -j 12 && sudo make modules_install -j 12 && sudo make install -j 12 103 | ``` 104 | 105 | After the build completes you'll get a list of what kernel modules have been installed. Mine looks like: 106 | ``` 107 | INSTALL drivers/hid/hid-generic.ko 108 | INSTALL drivers/hid/hid.ko 109 | INSTALL drivers/hid/usbhid/usbhid.ko 110 | INSTALL drivers/net/mii.ko 111 | INSTALL drivers/net/usb/cdc_ether.ko 112 | INSTALL drivers/net/usb/rndis_host.ko 113 | INSTALL drivers/net/usb/usbnet.ko 114 | INSTALL drivers/usb/class/cdc-acm.ko 115 | INSTALL drivers/usb/common/usb-common.ko 116 | INSTALL drivers/usb/core/usbcore.ko 117 | INSTALL drivers/usb/serial/ftdi_sio.ko 118 | INSTALL drivers/usb/phy/phy-generic.ko 119 | INSTALL drivers/usb/serial/usbserial.ko 120 | INSTALL drivers/usb/storage/usb-storage.ko 121 | INSTALL drivers/usb/usbip/usbip-core.ko 122 | INSTALL drivers/usb/usbip/vhci-hcd.ko 123 | DEPMOD 4.19.43-microsoft-standard 124 | ``` 125 | 126 | Build USBIP tools: 127 | ``` 128 | /usr/src/4.19.43-microsoft-standard$ cd tools/usb/usbip 129 | /usr/src/4.19.43-microsoft-standard/tools/usb/usbip$ sudo ./autogen.sh 130 | /usr/src/4.19.43-microsoft-standard/tools/usb/usbip$ sudo ./configure 131 | /usr/src/4.19.43-microsoft-standard/tools/usb/usbip$ sudo make install -j 12 132 | ``` 133 | 134 | Copy USBIP tools libraries to location that USBIP tools can get to them: 135 | ``` 136 | /usr/src/4.19.43-microsoft-standard/tools/usb/usbip$ sudo cp libsrc/.libs/libusbip.so.0 /lib/libusbip.so.0 137 | ```` 138 | 139 | Make a script in your home directory to modprobe in all the drivers. Be sure to modprobe in usbcore and usb-common first. I called mine startusb.sh. Mine looks like: 140 | ``` 141 | #!/bin/bash 142 | sudo modprobe usbcore 143 | sudo modprobe usb-common 144 | sudo modprobe hid-generic 145 | sudo modprobe hid 146 | sudo modprobe usbnet 147 | sudo modprobe cdc_ether 148 | sudo modprobe rndis_host 149 | sudo modprobe usbserial 150 | sudo modprobe usb-storage 151 | sudo modprobe cdc-acm 152 | sudo modprobe ftdi_sio 153 | sudo modprobe usbip-core 154 | sudo modprobe vhci-hcd 155 | echo $(cat /etc/resolv.conf | grep nameserver | awk '{print $2}') 156 | ``` 157 | The last line spits out the IP address of the Windows host. Helpful when you are attaching devices from it. 158 | If you see some crap about /bin/bash^M: bad interpreter: No such file or directory it's because you have cr+lf line endings. You need to convert your shellscript to just lf. 159 | 160 | Mark it as executable: 161 | ``` 162 | ~$ sudo chmod +x startusb.sh 163 | ``` 164 | 165 | Restart WSL. In a CMD window in Windows type: 166 | ``` 167 | C:\Users\rpasek>wsl --shutdown 168 | ``` 169 | 170 | Open WSL again by going to start menu and opening Ubuntu and run your script: 171 | ``` 172 | ~$ ./startusb.sh 173 | ``` 174 | 175 | Check in dmesg that all your USB drivers got loaded: 176 | ``` 177 | ~$ sudo dmesg 178 | ```` 179 | 180 | If so, cool, you've added USB support to WSL. 181 | 182 | ## Using USBIP-Win and USBIP on Linux 183 | 184 | This will generate a list of usb devices attached to Windows: 185 | ``` 186 | C:\Users\rpasek\usbip-win-driver>usbip list -l 187 | ``` 188 | 189 | The busid of the device I want to bind to is 1-220. Bind to it with: 190 | ``` 191 | C:\Users\rpasek\usbip-win-driver>usbip bind --busid=1-220 192 | ``` 193 | 194 | Now start the usbip daemon. I start in debug mode to see more messages: 195 | ``` 196 | C:\Users\rpasek\usbip-win-driver>usbipd --debug 197 | ``` 198 | 199 | Now on Linux get a list of availabile USB devices: 200 | ``` 201 | ~$ sudo usbip list --remote=172.30.64.1 202 | ``` 203 | 204 | The busid of the device I want to attach to is 1-220. Attach to it with: 205 | ``` 206 | ~$ sudo usbip attach --remote=172.30.64.1 --busid=1-220 207 | ``` 208 | 209 | Your USB device should be usable now in Linux. Check dmesg to make sure everything worked correctly: 210 | ``` 211 | ~$ sudo dmesg 212 | ``` 213 | 214 | ## Couple of tips 215 | 216 | * You need to bind to the base device of a composite device. Binding to children of a composite device does not work. 217 | * You can't bind hubs. Sorry, it would be really cool but it doesn't work. 218 | * If you'd like to unbind so you can access the device in Windows again: 219 | 1. Go into Device Manager in Windows, 220 | 2. Find the USB/IP STUB device under System devices, 221 | 3. Right click and select Update driver 222 | 4. Click Browse my computer for driver software 223 | 5. Click Let me pick from a list of available drivers on my computer 224 | 6. Select the original driver that Windows uses to access the device 225 | * Sometimes USBIP on Windows can't attach to a device. Try moving the device to a different hub and binding again. You can move the device back after you bind as binding sticks through attach/detach cycles. 226 | * I had some trouble on one of my machines getting composite devices to show up in usbip list on the Windows side. To get around this: 227 | 1. Download Zadig (https://zadig.akeo.ie) and run it 228 | 2. Go to options and select "List All Devices" and deselect "Ignore Hubs or Composite Parents" 229 | 3. Select your USB composite device in the list 230 | 4. Install the libusbK driver 231 | 5. Now your device should show up in the usbip list 232 | 6. I don't really know why this works. It might be that the Windows default driver captures the composite device in a way that USBIP-Win can't see it and installing the libusbK frees it. USBIP-Win will essentially overwrite the libusbK driver with the USBIP-Win driver so you might be able to select any driver (not just libusbK). Either way it's probably a bug that needs to be worked out in USBIP-Win 233 | --------------------------------------------------------------------------------