WSL2 Xbox Controllers - MacRover/maxwell GitHub Wiki

Custom Kernel

Before we can even connect an Xbox controller to WSL, we'll need to change to a custom kernel that supports gamepads (disabled by default).

On cmd:

git clone https://github.com/chosterto/WSL-CONFIGS.git

Then go to C:\Users\<USERNAME> and create a .wslconfig file if it doesn't already exist. Add the following lines into .wslconfig:

[wsl2]
kernel={DIR_TO_WSL-CONFIGS}\\kernel-xpad\\bzImage

{DIR_TO_WSL-CONFIGS} is the path to WSL-CONFIGS.

Then on cmd again, run:

wsl --shutdown

usbipd-win

Install usbipd on your Windows machine: https://github.com/dorssel/usbipd-win

There are provided instructions in the repo but to sum it up, open up a command prompt / PowerShell and run the command:

winget install usbipd

Then run the following and check if it works. If all goes well, you will get a list of all USB devices connected to your computer.

usbipd list

On WSL, run:

sudo apt install linux-tools-virtual hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20

Connect Xbox Controller to WSL2

Before connecting, we need to share devices. <BUSID> is the bus id of the Xbox controller which can be found by running usbipd list.

usbipd bind --force --busid <BUSID>

To connect a controller to your WSL:

usbipd wsl attach --busid <BUSID>

You can check if it is successful by running:

usbipd wsl list

The Xbox controller should say that it is attached to your WSL.

Udev Rules

Reading controller input requires sudo permissions by default. We'll need to write a rule to automatically give an input device root access. in WSL, navigate to /etc/udev/rules.d

cd /etc/udev/rules.d

Then, we need to create a file for the udev rule. You can name it however you like, but there is a conventional format you should follow. In my case, I named my rule 71-inputs.rules

sudo touch 71-inputs.rules

Add udev rule using the following command:

sudo bash -c "echo 'SUBSYSTEM==\"input\", MODE=\"0666\"' >> 71-inputs.rules"

You can specify which devices get certain permissions. For simplicity's sake, SUBSYSTEM=="input", MODE="0666" makes all input devices have read/write permissions.

Reload udev rules:

sudo udevadm control --reload-rules && sudo udevadm trigger

Udev rules not working?

Run the following command:

cd /etc/ && sudo bash -c "echo -e '[boot]\nsystemd=true' >> wsl.conf"

Shutdown your WSL client from PowerShell via wsl --shutdown

If that doesn't work, you can always do it manually:

sudo chmod 666 /dev/input/event0

Testing with ROS

Check if the controller works with ROS 2:

ros2 run joy joy_enumerate_devices

If it does, you should see the Xbox controller as part of the output.

You're all good to go!

⚠️ **GitHub.com Fallback** ⚠️