1. 安装usbipd,连接手柄至WSL
安装usbipd
usbipd-win 4.2.0https://github.com/dorssel/usbipd-win/releases/tag/v4.2.0
安装完成后,以管理员身份运行Windows Powershell,并查看当前设备:
(base) PS C:\WINDOWS\system32> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
2-2 045e:0b12 Xbox One Controller Not shared
3-3 8087:0029 英特尔(R) 无线 Bluetooth(R) Not shared
3-4 048d:c100 USB Input Device Not shared
5-1 03f0:6941 USB Input Device Not shared
5-2 046d:c08b USB Input Device Not shared
Persisted:
GUID DEVICE
可见手柄的BUSID为2-2。运行如下指令
(base) PS C:\WINDOWS\system32> usbipd bind --busid 2-2
再次列出usb设备,可见状态已转变为Shared
(base) PS C:\WINDOWS\system32> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
2-2 045e:0b12 Xbox One Controller Shared
3-3 8087:0029 英特尔(R) 无线 Bluetooth(R) Not shared
3-4 048d:c100 USB Input Device Not shared
5-1 03f0:6941 USB Input Device Not shared
5-2 046d:c08b USB Input Device Not shared
Persisted:
GUID DEVICE
打开一个新的终端(不必再以管理员身份运行),将手柄连接至WSL2
(base) PS C:\WINDOWS\system32> usbipd attach --wsl --busid 2-2
usbipd: info: Using WSL distribution 'Ubuntu-20.04' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Using IP address 172.18.128.1 to reach the host.
在同一终端启动WSL
(base) PS C:\Users\Administrator> wsl
使用lsusb命令查看当前设备,手柄Controller已经连接到WSL2
zichen@LAPTOP-OFE2M13C:/mnt/c/Users/Administrator$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 045e:0b12 Microsoft Corp. Controller
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
2. 编译WSL内核,使能手柄驱动
检查WSL更新
(base) PS C:\Users\Administrator> wsl --update
Checking for updates.
The most recent version of Windows Subsystem for Linux is already installed.
列出本地WSL发行版,确保当前使用的发行版为WSL2。如下图VERSION所示
(base) PS C:\Users\Administrator> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Running 2
备份当前WSL
wsl --export <current-distro> <temporary-path>\wsl2-usbip.tar
启动WSL并查看内核版本
zichen@LAPTOP-OFE2M13C:~$ uname -r
5.15.146.1-microsoft-standard-WSL2
安装编译Linux内核所需的依赖
zichen@LAPTOP-OFE2M13C:~$ sudo apt install build-essential flex bison dwarves libssl-dev libelf-dev
zichen@LAPTOP-OFE2M13C:~$ sudo apt install flex bison bc
使用wget工具下载源码包
zichen@LAPTOP-OFE2M13C:~$ wget https://github.com/microsoft/WSL2-Linux-Kernel/archive/refs/tags/linux-msft-wsl-5.15.146.1.tar.gz
--2024-06-10 22:41:16-- https://github.com/microsoft/WSL2-Linux-Kernel/archive/refs/tags/linux-msft-wsl-5.15.146.1.tar.gz
Resolving github.com (github.com)... 140.82.114.4
Connecting to github.com (github.com)|140.82.114.4|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/microsoft/WSL2-Linux-Kernel/tar.gz/refs/tags/linux-msft-wsl-5.15.146.1 [following]
--2024-06-10 22:41:17-- https://codeload.github.com/microsoft/WSL2-Linux-Kernel/tar.gz/refs/tags/linux-msft-wsl-5.15.146.1
Resolving codeload.github.com (codeload.github.com)... 140.82.113.10
Connecting to codeload.github.com (codeload.github.com)|140.82.113.10|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-gzip]
Saving to: ‘linux-msft-wsl-5.15.146.1.tar.gz’
linux-msft-wsl-5.15.146.1.tar [ <=> ] 189.85M 4.16MB/s in 59s
2024-06-10 22:42:16 (3.23 MB/s) - ‘linux-msft-wsl-5.15.146.1.tar.gz’ saved [199075681]
解压源码包并进入解压后的目录
zichen@LAPTOP-OFE2M13C:~$ tar -xzf linux-msft-wsl-5.15.146.1.tar.gz
zichen@LAPTOP-OFE2M13C:~$ cd WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1/
zichen@LAPTOP-OFE2M13C:~/WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1$
使用make工具编译linux内核
zichen@LAPTOP-OFE2M13C:~/WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1$ make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl
弹出图形化配置界面
下移找到Device Drivers, 按Enter进入
找到Input Device Support
按y使能Joystick Interface与Joysticks/Gamepads(使能前括号为空,使能后出现星号)。后者使能后,回车进入子菜单,依次使能X-Box gamepad support、X-Box gamepad rumble support(使能前者后出现)。
选择save保存后,多次Exit退出图形化界面。
编译Linux内核,有两种可选的编译方式;
1. 将驱动编译进内核,生成压缩后的内核。此处采用了这种方式。
zichen@LAPTOP-OFE2M13C:~/WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1$ make -j$(nproc) bzImage KCONFIG_CONFIG=Microsoft/config-wsl
2. 将驱动作为内核模组编译后手动加载。此处不过多涉及。
make -j$(nproc) modules KCONFIG_CONFIG=Microsoft/config-wsl
make -j$(nproc) modules_install KCONFIG_CONFIG=Microsoft/config-wsl
编译完成后的内核路径如下:
Kernel: arch/x86/boot/bzImage is ready (#1)
将内核复制到Windows 10的E盘,并重命名为kernel
zichen@LAPTOP-OFE2M13C:~/WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1$ ls /mnt
c d e wsl wslg
zichen@LAPTOP-OFE2M13C:~/WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1$ cp arch/x86/boot/bzImage /mnt/e
退出并关闭WSL:
(base) PS C:\Users\Administrator> wsl --shutdown
(base) PS C:\Users\Administrator> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Stopped 2
在Windows用户目录C:\Users\{username}下创建.wslconfig配置文件,并将其指向新生成的内核。注意此处需要使用双反斜杠:
[wsl2]
kernel=E:\\kernel
重新启动WSL并检查内核,发现内核编译时间已经改变,可见WSL已经从新的内核启动。
zichen@LAPTOP-OFE2M13C:~$ uname -a
Linux LAPTOP-OFE2M13C 5.15.146.1-microsoft-standard-WSL2 #1 SMP Mon Jun 10 23:08:46 MDT 2024 x86_64 x86_64 x86_64 GNU/Linux
重新连接手柄并检查,发现js0可以找到,说明手柄驱动已经使能
(base) PS C:\Users\Administrator> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
2-2 045e:0b12 Xbox One Controller Shared
3-3 8087:0029 英特尔(R) 无线 Bluetooth(R) Not shared
3-4 048d:c100 USB Input Device Not shared
5-1 03f0:6941 USB Input Device Not shared
5-2 046d:c08b USB Input Device Not shared
Persisted:
GUID DEVICE
(base) PS C:\Users\Administrator> usbipd attach --wsl --busid 2-2
usbipd: info: Using WSL distribution 'Ubuntu-20.04' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Using IP address 172.18.128.1 to reach the host.
zichen@LAPTOP-OFE2M13C:/mnt/c/Users/Administrator$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 045e:0b12 Microsoft Corp. Controller
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
zichen@LAPTOP-OFE2M13C:/mnt/c/Users/Administrator$ ls /dev/input/
by-id by-path js0
在sudo权限下,下载并运行手柄例程
zichen@LAPTOP-OFE2M13C:~$ sudo apt-get install joystick -y
zichen@LAPTOP-OFE2M13C:~$ sudo jstest /dev/input/js0
Driver version is 2.1.0.
Joystick (Microsoft Xbox One X pad) has 8 axes (X, Y, Z, Rx, Ry, Rz, Hat0X, Hat0Y)
and 11 buttons (BtnA, BtnB, BtnX, BtnY, BtnTL, BtnTR, BtnSelect, BtnStart, BtnMode, BtnThumbL, BtnThumbR).
Testing ... (interrupt to exit)
Axes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5: 0 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5:-32767 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5:-32767 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:oAxes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5:-32767 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off
操作手柄,输出发生变化,手柄成功连接。
参考链接与博客
感谢各位前辈和开发者的经验分享🌹