在 Arch@WSL2 中启用 systemd , GUI 与 GPU加速
Published:
众所周知, Ubuntu in WSL2 是微软和Ubuntu的亲儿子, 从两边都得到了最好的支持, 开箱即用.
而 Arch in WSL 是纯纯的野孩子, 微软和Arch两边都不管的, 想要在其中启用 systemd , GUI 与 GPU加速, 会碰到许多坑, 这篇文章把坑全给填平.
以下方法在 2024-3 的 Windows11-23H2-22631.3235 中测试通过.
理论上应该在所有支持 WSLg 和 systemd 的 WSL Linux 发行版中都有效.
2024-6-23 Arch 更新 systemd-256
后必须禁用 cgroup-v1
.
Prepare 准备
- ensure WSL components and Arch packages are all updated.
确保 WSL 组件和 Arch 包已更新.PS> wsl --update Checking for updates. The most recent version of Windows Subsystem for Linux is already installed.
Arch$ sudo pacman -Syuu :: Synchronizing package databases... core is up to date extra is up to date :: Starting full system upgrade... there is nothing to do
- edit
/etc/wsl.conf
to enable systemd.
修改/etc/wsl.conf
以启用 systemd.[boot] systemd=true
- create
/etc/tmpfiles.d/wslg.conf
.
创建/etc/tmpfiles.d/wslg.conf
1.# Type Path Mode UID GID Age Argument L+ /tmp/.X11-unix - - - - /mnt/wslg/.X11-unix
- create
~/.config/user-tmpfiles.d/wslg.conf
.
创建~/.config/user-tmpfiles.d/wslg.conf
.# Type Path Mode UID GID Age Argument L+ %t/wayland-0 - - - - /mnt/wslg/runtime-dir/wayland-0 L+ %t/wayland-0.lock - - - - /mnt/wslg/runtime-dir/wayland-0.lock L+ %t/pulse/native - - - - /mnt/wslg/runtime-dir/pulse/native L+ %t/pulse/pid - - - - /mnt/wslg/runtime-dir/pulse/pid
- execute command below to enable
~/.config/user-tmpfiles.d/wslg.conf
.
执行下面的命令以启用~/.config/user-tmpfiles.d/wslg.conf
.systemctl --user enable systemd-tmpfiles-setup.service systemd-tmpfiles-clean.timer
- add current user to group
video
,render
把当前用户加入用户组video
,render
sudo usermod --append --groups video,render user1
- edit
%UserProfile%/.wslconfig
to disablecgroup-v1
in windows, see 2. New Added in 2024-6-23
在 Windows 中编辑%UserProfile%/.wslconfig
以禁用cgroup-v1
, 参见 2. 2024-6-23 新加入
You must do so fromsystemd-256
.
Arch 系统更新systemd-256
及后续版本后, 此步骤必做.[wsl2] kernelCommandLine = cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1
- restart Arch@WSL2 in Windows PowerShell.
在 Windows PowerShell 中 重启 Arch@WSL2.wsl.exe --shutdown
Install and check 安装并检查
Enter Arch terminal.
进入 Arch 终端.
- Mesa(OpenGL,GLX,EGL,GLES)
$ sudo pacman -S mesa mesa-utils $ glxinfo -B | grep render direct rendering: Yes OpenGL renderer string: D3D12 (Your GPU) $ eglinfo -B $ glxgears $ eglgears_wayland
- Vulkan
vulkan-dzn
for using D3D12 over GPU is unavailable, so we can only usevulkan-swrast
to run Vulkan over CPU.- 包
vulkan-dzn
用于通过 D3D12 调用 GPU, 但 Arch 不包含, 只能用vulkan-swrast
来使用 CPU.$ sudo pacman -S vulkan-swrast vulkan-tools $ vulkaninfo GPU id : 0 (llvmpipe (LLVM 16.0.6, 256 bits)): $ vkgears $ vkcube
- You can compile mesa to get
libvulkan_dzn.so
(vulkan-dzn
) - 可以重新编译 mesa 得到
libvulkan_dzn.so
(vulkan-dzn
)$ sudo pacman -U vulkan-dzn-24.0.2-2.tar.zst $ vulkaninfo GPU id : 0 (Microsoft Direct3D12 (Your GPU)):
- VA-API
- Currently,
vainfo
fails on x11 and wayland. - 当前,
vainfo
不能在 x11 和 wayland 上运行.$ sudo pacman -S libva libva-mesa-driver libva-utils $ vainfo --display drm Trying display: drm vainfo: VA-API version: 1.20 (libva 2.20.1) vainfo: Driver version: Mesa Gallium driver 24.0.2-arch1.1 for D3D12 (Your GPU) vainfo: Supported profile and entrypoints VAProfileH264ConstrainedBaseline: VAEntrypointVLD
- Currently,
- VDPAU
- Currently,
vdpauinfo
fails over D3D12. - 当前,
vdpauinfo
调用 D3D12 驱动失败.$ sudo pacman -S libvdpau mesa-vdpau vdpauinfo $ VDPAU_DRIVER=d3d12 vdpauinfo
- So use
vdpauinfo
over VA-API by packagelibvdpau-va-gl
. But VA-API fails on x11, and VDPAU only runs on x11. - 所以安装包
libvdpau-va-gl
来使vdpauinfo
调用 VA-API 驱动. 但 VA-API 不能在 x11 运行, 而 VDPAU 只支持 x11.
$ sudo pacman -S libvdpau-va-gl $ VDPAU_DRIVER=va_gl vdpauinfo display: :0 screen: 0 API version: 1 Information string: OpenGL/VAAPI backend for VDPAU Video surface: name width height types ------------------------------------------- 420 4096 4096 NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 NV24 YV24 P010 P016 Y_U_V_444_16
- Currently,
- OpenCL
- I cannot determine which driver should be used in WSL2.
- 不知道在 WSL2 中该用哪个驱动.
$ sudo pacman -S ocl-icd opencl-rusticl-mesa clinfo $ clinfo
- NVidia: opencl-nvidia
- AMD: rocm-opencl-runtime
- Intel: intel-compute-runtime
- Mesa: opencl-rusticl-mesa opencl-clover-mesa
Lib Details 运行库详情
In website https://pkgs.org , you can use filename below (libvulkan_lvp.so
) to search package name in your distro.
可以在网站 https://pkgs.org 中, 用下面的文件名(libvulkan_lvp.so
)来搜索你的发行版对应的包名.
API | lib | driver | drivers | info util | test utils |
---|---|---|---|---|---|
GLX | libGLX*.so | d3d12_dri.so | /usr/lib/dri/*_dri.so | glxinfo | glxgears |
EGL | libEGL*.so | d3d12_dri.so | /usr/lib/dri/*_dri.so | eglinfo | eglgears_wayland, eglgears_x11 |
GLES | libGLESv2.so | d3d12_dri.so | /usr/lib/dri/*_dri.so | es2_info | es2gears_wayland, es2gears_x11 |
Vulkan | libvulkan.so | libvulkan_lvp.so libvulkan_dzn.so | /usr/lib/libvulkan_*.so | vulkaninfo | vkcube-wayland, vkcube |
VA-API | libva.so, libva-*.so | d3d12_drv_video.so | /usr/lib/dri/*_drv_video.so | vainfo | |
VDPAU | libvdpau.so | libvdpau_d3d12.so libvdpau_va_gl.so | /usr/lib/vdpau/libvdpau_*.so | vdpauinfo | |
OpenCL | libOpenCL.so | libRusticlOpenCL.so | /usr/lib/lib*OpenCL.so | clinfo |
Glitches in GUI 程序花屏
- Enter WLSg system distro, and restart weston.
- 进入 WLSg 系统发行版, 重启 weston.
PS> wsl --system
wslg$ ps -A | grep weston
10 ? 00:00:09 weston
349 ? 00:00:00 weston-rdprail-
wslg$ kill -9 10
wslg$ ps -A | grep weston
707 ? 00:00:00 weston
777 ? 00:00:00 weston-rdprail-
wslg$ exit
logout
Problems 问题
- cannot open display: :03
- Error: couldn’t open display :0
- Error: unable to open display :0
- XCB failed to connect to the X server due to error:1.
- EGLUT: failed to initialize native display
- qt.qpa.xcb: could not connect to display :0
- Failed to create wl_display (No such file or directory)
Troubleshooting 故障诊断
- check environment variables
检查环境变量$ env | grep -E "XDG|DISPLAY|PULSE" DISPLAY=:0 WAYLAND_DISPLAY=wayland-0 PULSE_SERVER=unix:/mnt/wslg/PulseServer XDG_RUNTIME_DIR=/run/user/1000/
- check dev files
检查设备文件$ ls -l /dev/dxg /dev/dri/card0 /dev/dri/renderD128 crw-rw---- 1 root video 226, 0 Mar 6 18:49 /dev/dri/card0 crw-rw-rw- 1 root render 226, 128 Mar 6 18:49 /dev/dri/renderD128 crw-rw-rw- 1 root root 10, 127 Mar 6 18:49 /dev/dxg
- If you have two or more distros installed in WSL2, the last started distro may recreate the dev files even in the first started distro, and make the owner group mismatch in the first distro4.
- 如果你在 WSL2 里安装了多个发行版, 后启动的发行版会重新创建这些设备文件, 甚至会影响先启动的发行版, 导致这些设备文件用户组混乱4.
$ ls -l /dev/dxg /dev/dri/card0 /dev/dri/renderD128 crw-rw---- 1 root 985 226, 0 Mar 6 18:52 /dev/dri/card0 crw-rw-rw- 1 root 989 226, 128 Mar 6 18:52 /dev/dri/renderD128 crw-rw-rw- 1 root root 10, 127 Mar 6 18:52 /dev/dxg $ cat /etc/group | grep -E "video|render" video:x:44:user1 render:x:110:user1
- check display sockets
检查 X11 和 wayland 的 socket 文件- 4 files and 1 dir must link to
/mnt/wslg/*
- 下面的4个文件和1个目录必须链接到
/mnt/wslg/*
$ ls -ld /tmp/.X11-unix $XDG_RUNTIME_DIR/wayland* $XDG_RUNTIME_DIR/pulse/* lrwxrwxrwx 1 user1 user1 34 Mar 6 18:49 /run/user/1000//pulse/native -> /mnt/wslg/runtime-dir/pulse/native lrwxrwxrwx 1 user1 user1 31 Mar 6 18:49 /run/user/1000//pulse/pid -> /mnt/wslg/runtime-dir/pulse/pid lrwxrwxrwx 1 user1 user1 31 Mar 6 18:49 /run/user/1000//wayland-0 -> /mnt/wslg/runtime-dir/wayland-0 lrwxrwxrwx 1 user1 user1 36 Mar 6 18:49 /run/user/1000//wayland-0.lock -> /mnt/wslg/runtime-dir/wayland-0.lock lrwxrwxrwx 1 root root 19 Mar 6 18:49 /tmp/.X11-unix -> /mnt/wslg/.X11-unix
- 4 files and 1 dir must link to
- check group permissions
检查用户组和权限$ groups video render wheel user1
Reasons 原因
/init
which is from Microsoft create the 5 links above to/mnt/wslg/*
.
/init
(来自微软)创建了上述的5个链接,正确指向/mnt/wslg/*
.- systemd mount and tmpfiles service recreate
/tmp
and/run/user/1000
, and make them empty.
systemd 的 mount(挂载文件系统) 和 tmpfiles(创建临时目录) 两个服务重新创建了/tmp
和/run/user/1000
, 使之清空. - we’d use tmpfiles service to recreate the 5 links after step 2.
我们就用 tmpfiles 服务在步骤2. 之后重新创建5个链接.
/etc/tmpfiles.d/wslg.conf
,~/.config/user-tmpfiles.d/wslg.conf
- What does Ubuntu do?
Ubuntu has disabled mounting/tmp
and/run/user/1000
astmpfs
, so links created by/init
won’t be cleared.
Ubuntu 是怎么做的?
Ubuntu 禁用了作为tmpfs
挂载/tmp
和/run/user/1000
, 所以/init
创建的链接不会被清除.Ubuntu$ mount | grep -E "user|tmp" none on /tmp/.X11-unix type tmpfs (ro,relatime) none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755) none on /run/user type tmpfs (rw,relatime)
Arch$ mount | grep -E "user|tmp" tmpfs on /tmp type tmpfs (rw,nosuid,nodev,size=8131748k,nr_inodes=1048576) none on /tmp/.X11-unix type tmpfs (ro,relatime) none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755) none on /run/user type tmpfs (rw,relatime) tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=1626348k,nr_inodes=406587,mode=700,uid=1000,gid=1000) tmpfs on /mnt/wslg/run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=1626348k,nr_inodes=406587,mode=700,uid=1000,gid=1000)