本文介绍的办法能够通过 Windows 侧安装的 USBIP 来将 USB 数据包转发至 Linux 侧的 USBIP,从而让 WSL 2 支持 USB 设备。默认情况下,WSL 2 的 Linux 内核并不支持 USB(WSL2 6.1 版本之后的新内核已经支持了),本文将介绍如何向 WSL 2 的 Linux 内核中添加 USB 功能,以及如何用 USBIP 将 USB 设备连接至 Linux 上。
第一步:安装 USBIPD-WIN 连接 USB 设备
如果已经安装了 winget,在 Windows PowerShell 中直接安装即可
> winget install usbipd
第二步:附加 USB 设备到 WSL 2
在附加 USB 设备之前,请确保 WSL 命令行已打开。 这将使 WSL 2 轻型 VM 保持活动状态。
通过以管理员模式打开 PowerShell 并输入以下命令,列出所有连接到 Windows 的 USB 设备。 列出设备后,选择并复制要附加到 WSL 的设备总线 ID。
> usbipd list
在附加 USB 设备之前,必须使用命令 usbipd bind 来共享设备,从而允许它附加到 WSL。 这需要管理员权限。 选择要在 WSL 中使用的设备总线 ID,然后运行以下命令。 运行命令后,请再次使用命令 usbipd list 验证设备是否已共享。
> usbipd bind --busid 4-4
若要附加 USB 设备,请运行以下命令。 (不再需要使用提升的管理员提示。)确保 WSL 命令提示符处于打开状态,以使 WSL 2 轻型 VM 保持活动状态。 请注意,只要 USB 设备连接到 WSL,Windows 将无法使用它。 附加到 WSL 后,任何作为 WSL 2 运行的分发版本都可以使用 USB 设备。 使用 usbipd list 验证设备是否已附加。 在 WSL 提示符下,运行 lsusb 以验证 USB 设备是否已列出,并且可以使用 Linux 工具与之交互。
> usbipd attach --wsl --busid <busid>
打开 Ubuntu(或首选的 WSL 命令行),使用以下命令列出附加的 USB 设备:
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 004: ID 0951:1624 Kingston Technology DataTraveler G2
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
# 也可以使用 dmesg 查看内核信息
$ sudo dmesg
# /dev/sdd1 /dev/sdd2 是加载成功的 usb 磁盘,如果已经成功,则可忽略第三步
$ ls /dev/sd*
/dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sdd1 /dev/sdd2
$ ls /dev/ttyUSB*
/dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sdd1 /dev/sdd2
# 挂载使用
$ sudo mkdir /mnt/test; sudo mount /dev/sdd2 /mnt/test
你应会看到刚刚附加的设备,并且能够使用常规 Linux 工具与之交互。 根据你的应用程序,你可能需要配置 udev 规则以允许非根用户访问设备。
在 WSL 中完成设备使用后,可物理断开 USB 设备,或者从 PowerShell 运行此命令:
> usbipd detach --busid <busid>
# 或
> usbipd detach -a
第三步:向 Linux 侧添加 USB 支持 WSL 2 Ubuntu 最新版本开启 Systemd 默认支持 Serial devices
这里我们将手动编译最新的 WSL2 Linux 内核,请注意可能出现的任何问题。缺啥安装啥
在 WSL 中,下载安装编译 Linux 内核所需要的库和工具:
解决方案参考信息:无法再访问 WSL2 中的 FTDI 设备
$ git clone https://github.com/microsoft/WSL2-Linux-Kernel.git --depth=1 -b linux-msft-wsl-6.6.y
$ sudo apt update
$ sudo apt -y install build-essential flex bison libssl-dev libelf-dev bc cpio
$ sudo apt -y install python3 pahole
$ cd WSL2-Linux-Kernel
## This line turns the FTDI driver from disabled or module to builtin
# 不需要,新版改成了module模式,配合systemd实现了自动加载 $ ./scripts/config --file Microsoft/config-wsl --set-val CONFIG_USB_SERIAL_FTDI_SIO y
## This line turns the CH341 driver from disabled or module to builtin
# 不需要,新版改成了module模式,配合systemd实现了自动加载 $ ./scripts/config --file Microsoft/config-wsl --set-val CONFIG_USB_SERIAL_CH341 y
$ make -j$(nproc) KCONFIG_CONFIG=Microsoft/config-wsl
# 安装 modules
$ sudo make modules_install headers_install
## 配置 WSL 2 使用新内核 Use another target directory if you don't want the kernel in the root of C:\
$ cp arch/x86/boot/bzImage /mnt/c/Users/yugua/bzImage-6.6
$ vi /mnt/c/Users/yugua/.wslconfig
$ cat !$
cat /mnt/c/Users/yugua/.wslconfig
[wsl2]
kernel=C:\\Users\\yugua\\bzImage-6.6
第四步:重启 WSL 2 使新内核生效
在 Windows PowerShell 中重启 WSL 2
> wsl --shutdown
重启 WSL2 后,附加 USB 设备到 WSL 2
> usbipd bind --busid 1-7
> usbipd attach --wsl --busid 1-7
> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
1-1 32c2:0015 USB 输入设备 Not shared
1-7 067b:2303 PL2303HXA PHASED OUT SINCE 2012. PLEASE CONTACT YOUR SUPP... Attached
1-14 0bda:4853 Realtek Bluetooth Adapter Not shared
在 dmesg 中检测确保我们所有的 USB 驱动都载入成功:
# 确认使用了新内核
$ uname -r
6.6.87.1-microsoft-standard-WSL2+$ sudo dmesg
# lsusb
$ lsusb
$ sudo dmesg
$ ls /dev/sd*
$ ls /dev/ttyUSB*
$ sudo apt instal libnfc-bin
$ sudo apt install mfoc
$ nfc-list
nfc-list uses libnfc 1.8.0
NFC device: microBuilder.eu opened
1 ISO14443A passive target(s) found:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): bd 9d 0c af
SAK (SEL_RES): 08