USB Serial and Embedded Development in WSL 2
Use usbipd-win to pass a serial adapter or debug probe into WSL, identify Linux devices reliably, and validate permissions and firmware workflows.
USB serial adapters, development boards, and debug probes are common Linux tools that do not automatically appear inside WSL just because they are plugged into a Windows laptop. WSL 2 runs a Linux kernel in a managed virtual machine. Windows owns the physical USB device until an explicit USB/IP attachment hands it to the guest. After that handoff, Linux still needs the right kernel driver, device node, permissions, and application protocol. Treating these as separate steps turns an unreliable “port not found” experience into a repeatable embedded workflow.
This guide covers the Windows-to-WSL attachment path and the Linux serial-validation path. It does not promise that every USB device or vendor tool works through USB/IP, nor that an attached USB serial port is equivalent to a Windows COM-port mapping. Device firmware, interface layout, driver support, baud rate, and application behavior remain device-specific.
Confirm prerequisites and ownership
Microsoft’s current USB guide targets WSL 2 and describes usbipd-win 5.0.0 or later. It documents a Linux kernel requirement of 5.10.60.1 or later, with current WSL Store installations receiving updated kernels through wsl --update. Record Windows architecture and build, wsl.exe --version, the distro’s WSL version, and uname -r before troubleshooting. WSL 1 does not provide the USB/IP route described here.
Install usbipd-win using Microsoft’s linked project instructions. Its Windows service exposes USB devices to USB/IP clients, while WSL supplies the Linux client and device-class drivers. Binding marks a device as shareable and requires an elevated Windows prompt; attaching connects it to WSL and normally does not require elevation once it has been bound. The device cannot be used by Windows while it is attached to Linux. The binding state can persist across restart, but the active attachment is not persistent and must be re-established after WSL restarts or the device is unplugged.
The two operating systems cannot safely own the same USB interface at the same time. Close Windows applications that have claimed a serial adapter or debug probe before attaching it. For a composite device, Linux may see multiple interfaces; the kernel driver and the tool must match the interface you intend to use. Attaching proves transport-level availability, not that a flashing tool, debugger, or serial protocol is compatible.
Attach the device with explicit Windows steps
Keep a WSL terminal open so the WSL 2 VM is active. In an elevated PowerShell window, list devices and bind the chosen bus ID:
usbipd list
usbipd bind --busid 4-4
usbipd list
Replace 4-4 with the current bus ID from the listing. Do not save it as a permanent identifier: bus IDs can change after a device reconnects or moves to another port. Once the device shows as shared, attach from a normal PowerShell session:
usbipd attach --wsl --busid 4-4
usbipd list
The official Microsoft procedure says the attached device can be used from any WSL 2 distribution. From Linux, lsusb should show the USB device. When finished, close the serial/debug application cleanly and detach it from PowerShell:
usbipd detach --busid 4-4
Unplugging or restarting WSL also disconnects the active attachment, but explicit detach makes ownership changes visible and repeatable. Do not detach during a firmware erase/write or other operation whose interruption can leave the target in an incomplete state.
Observe enumeration before choosing a tty name
Start Linux event observation before attaching the device so the kernel’s messages are captured:
sudo dmesg --follow
In another WSL terminal, watch udev and list the bus/device topology:
sudo udevadm monitor --kernel --udev
lsusb -t
After attachment, the kernel may create /dev/ttyUSB0, /dev/ttyUSB1, /dev/ttyACM0, or another node depending on the driver and discovery order. A board that exposes a USB CDC ACM interface commonly uses a ttyACM node; many USB-to-UART bridge chips use a ttyUSB node. These names describe the Linux driver’s device node, not a stable physical identity. A reconnect or another adapter can change the number.
Inspect available nodes and, when present, the persistent by-id links:
ls -l /dev/ttyUSB* /dev/ttyACM* 2>/dev/null
ls -l /dev/serial/by-id 2>/dev/null
Use /dev/serial/by-id/... when the adapter exposes a usable USB serial number and udev creates that link. If the device has no unique serial descriptor, there may be no reliable by-id name; match its USB vendor/product information and confirm the current dmesg event rather than assuming the first tty is the intended board. udevadm info --query=property --name=/dev/ttyUSB0 can expose properties for a node once you have identified it.
If no tty node appears, separate USB enumeration from serial support. lsusb can succeed even when no class driver binds. Check dmesg for the interface and driver probe, inspect lsusb -t, and verify that the distro’s WSL kernel includes the relevant module. Common USB serial driver names include cdc_acm, cp210x, ftdi_sio, and ch341, but the exact driver depends on the device. Do not download an arbitrary out-of-tree driver until the device’s VID:PID, kernel support, and vendor documentation establish that one is necessary.
Permissions are a separate layer from attachment
An attached port can exist and still return Permission denied for an ordinary user. Inspect owner, group, and mode with stat or ls -l, then compare the node’s group with id and the distro’s group database. Many Debian-derived systems use a dialout group for serial devices; other distributions may use a different group or rule. Do not assume one group name is portable.
If an application must run without sudo, use a distro-appropriate udev rule that matches the specific adapter and grants the intended local access. The usbipd-win WSL instructions note that udev rules may be needed and should be in place before attachment. Reload the rules using the distribution’s supported udev procedure, then detach and reattach so the rule is applied to a new device event. Prefer a match based on verified vendor/product and serial attributes over a broad rule matching every USB device. Group membership changes require a new login session before they appear in id.
For each change, retest the actual application as the intended user. A shell that can list the device as root does not establish that a GUI IDE or user service can open it. If access fails, record the exact node, ownership, process user, and error. Avoid changing permissions to 0666 as a blanket workaround; it hides the rule mismatch and applies access more broadly than the serial application needs.
Validate serial settings with a controlled target
A tty device node does not define the serial protocol. Check the board’s documentation for baud rate, data bits, parity, stop bits, flow control, voltage levels, and which pins carry its console. Serial TTL and RS-232 electrical levels are different. A protocol mismatch can produce garbage characters even when USB/IP and the Linux driver are working correctly.
For a conventional 115200 baud, 8-N-1 console, configure a candidate port and read a short, known boot or diagnostic message:
sudo stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parenb raw -echo
timeout 10 cat /dev/ttyUSB0
Replace the path and serial parameters with the values required by the device. stty configures the line discipline but does not guarantee that the board is transmitting; use a controlled loopback or a documented console message to establish end-to-end behavior. For interactive sessions, a terminal such as picocom can open the port at an explicit baud rate, but close it before another program or debugger claims the same port. For automated jobs, specify open/read timeouts and handle device removal rather than waiting forever on a disconnected tty.
A flashing or debug probe may not expose any serial node at all. It can be present as a USB device and still require OpenOCD, a vendor utility, a kernel driver, udev permissions, or a debug interface configuration. Verify each layer in sequence: USB bus visibility, interface/driver binding, expected device node or libusb access, user permissions, and a harmless probe/read command. Start with the vendor’s documented identify operation; do not start a destructive flash as the first connectivity test.
Make reconnects and recovery intentional
For repeatable lab work, save the device’s USB VID:PID and serial descriptor, the current bus ID only as a runtime value, Linux kernel version, attached driver, tty link, udev rule, tool version, and port settings. At session start, verify usbipd list on Windows, attach the intended device, inspect dmesg, and resolve the current Linux node. At session end, close tools and detach explicitly. This short checklist prevents a second adapter from silently becoming /dev/ttyUSB0 and receiving a command intended for the first board.
When an attachment disappears, first check whether WSL or the USB device restarted, then check usbipd list and reattach using the current bus ID. If USB enumeration succeeds but the tty vanishes, investigate driver binding and kernel events. If the tty remains but reads fail, verify permissions and serial settings. If a flash operation reports transport errors, use the tool’s verbose log and the board vendor’s recovery process before assuming WSL is at fault. The USB/IP transport adds a virtualization and network-style boundary, so timing-sensitive or unusual devices deserve a representative test under the exact workload before they become a production dependency.
Acceptance means more than a successful attach: Linux identifies the expected USB device; the expected driver or userspace interface is present; the normal user can access it; a safe, documented serial/debug exchange succeeds; WSL restart and reattachment are understood; and Windows regains the device after detach. Keep firmware writes and other irreversible operations away from an untested path until those checks pass.
Related:
- USB in WSL 2: How usbipd-win Attaches Devices over USB/IP
- The Linux Kernel Microsoft Actually Maintains for WSL2
Sources: