Search notes:

Windows Subsystem for Linux (WSL)

WSL was introduced in 2016. It promises to run unmodified Linux binaries in Windows 10. (And with Build 14951, it is also possible to run Windows executables from a WSL distribution).

WSL versions

As of this writing, there are two WSL versions: WSL 1 and WSL 2.
WSL 2 has the following three features that are not present in WSL 1: On the other hand, WSL 2 lacks Performance across OS file systems.
Generally, Microsoft recommends to use WSL 2 if possible. However, accessing the Windows file system from WSL 2 is slower than if accessed from WSL 1.
The default version can be set (here to 2) with:
c:> wsl --set-default-version 2

WSLg

WSLg is the abbreviation for Windows Subsystem for Linux GUI. This component enables GUI applications in WSL. The fundament of WSLg is the Weston compositor.
Audio (in and out) is supported by a PulseAudio server.

WSLGd

WSLGd is the first process launched after init. This process is similar to a daemon and
  • starts Weston (with XWayland) and PulseAudio and
  • then launces mstsc.exe on the host in silent mode in order to establish an RDP connection.
There seems to be no visible process or an executable (binary) with this name.

System Distro

The WSLg System Distro is a containerized Linux environment based on CBL-Mariner where the following components are running.
Env var
WSLg XServer $DISPLAY
Wayland server $WAYLAND_DISPLAY
PulseAudio server $PULSE_SERVER

Misc

See also Steve Pronovost's post on the WSLg architecture.
/mnt/wslg, /mnt/wslg/distro/, /mnt/c/ProgramData/Microsoft/WSL/.wslgconfig

Enabling WSL in a Windows console

WSL must be specifically enabled before it can be started. It's possible to enable WSL from the command line with elevated privileges. In order for the enabling to take effect, the computer needs to be restarted.
WSL (Version 1?) is enabled cmd.exe with
C:\> dism /online /enable-Feature /featureName:Microsoft-Windows-Subsystem-Linux
In PowerShell, it can be enabled with
PS:\> enable-WindowsOptionalFeature -online -featureName microsoft-Windows-Subsystem-Linux

Distribution(s)

After the Subsystem for Linux is installed, a distribution needs to be chosen:
C:\Users\Rene> bash
Windows Subsystem for Linux has no installed distributions.
Distributions can be installed by visiting the Microsoft Store:
https://aka.ms/wslstore

Finding distributions

Distributions that are available from the online store can be listed like so:
C:\> wsl --list --online
The following is a list of valid distributions that can be installed.
The default distribution is denoted by '*'.
Install using 'wsl --install -d <Distro>'.

  NAME                                   FRIENDLY NAME
* Ubuntu                                 Ubuntu
  Debian                                 Debian GNU/Linux
  kali-linux                             Kali Linux Rolling
  Ubuntu-18.04                           Ubuntu 18.04 LTS
  Ubuntu-20.04                           Ubuntu 20.04 LTS
  Ubuntu-22.04                           Ubuntu 22.04 LTS
  OracleLinux_8_5                        Oracle Linux 8.5
  OracleLinux_7_9                        Oracle Linux 7.9
  SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
  openSUSE-Leap-15.4                     openSUSE Leap 15.4
  openSUSE-Tumbleweed                    openSUSE Tumbleweed
A list of downloadable (.appx) distributions is here.

Install distro

wsl --install --distribution Debian

WslRegisterDistribution failed with error: 0x800701bc

2023-05-18 on a new laptop, when trying to install Debian, I received the error 0x800701bc along with a link to https://aka.ms./wsl2kernel where I could find more information.
This link told me to install the Linux kernel update.

WslRegisterDistribution failed with error: 0x80370102

Still on the 2023-05-18 on a new laptop after updating the kernel, I got the 0x800701bc error along with a link to https://aka.ms./enablevirtualization.
This link suggested to enable hypervisor launch in the boot configuration with bcdedit.exe:
bcdedit /set hypervisorlaunchtype Auto
However, even after rebooting the system and verifying that virtualization was enabled in the BIOS, this didn't work.
The next attempt was to enable VirtualMachinePlatform (which then seemed to finally work!)
PS:\> enable-WindowsOptionalFeature -online -featureName VirtualMachinePlatform -all

Old attempts

(The following describes an unsuccessful attempt of mine to install a distribution).
Download links for the distros can be found here and here.
    $ProgressPreference = 'SilentlyContinue'   ## Does this make the download time shorter???
rem invoke-webRequest -Uri https://aka.ms/wsl-ubuntu-1604    -outFile Ubuntu.appx -useBasicParsing
    invoke-webRequest -Uri https://aka.ms/wsl-kali-linux-new -outFile kali.appx   -useBasicParsing

    add-appxPackage .\kali.appx
Unfortunately, even after executing add-appxPackage …, there is no distribution installed:
C:\Users\Rene> wsl
Windows Subsystem for Linux has no installed distributions.
Distributions can be installed by visiting the Microsoft Store:
https://aka.ms/wslstore

Removing a distro

C:\> wsl --unregister <distro name>

Location

The distributions are stored in %LOCALAPPDATA%\Packages\-WSL distro-

Update WSL 1 to WSL 2

In order to be able to use WSL 2, the Virtual Machine Platform optional feature must be enabled:
C:\users\rene> wsl --set-default-version 2
Please enable the Virtual Machine Platform Windows feature and ensure virtualization is enabled in the BIOS
For information please visit https://aka.ms/wsl2-install
The Virtual Machine Platform can be enabled like so (with elevated privileges):
C:\users\rene> dism /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
However, I still receive an error:
C:\users\rene> wsl --set-default-version 2
Error: 0x1bc
For information on key differences with WSL 2 please visit https://aka.ms/wsl2
This thread seems to contain some information on how to get around this issue. It is suggested that the kernel needs to be installed into C:\Windows\System32\lxss\tools.
I was able to to that by updating the Linux kernel.
Installing (updating) the kernel seemed to work, setting the default version to 2 works now:
C:\users\rene> wsl --set-default-version 2
For information on key differences with WSL 2 please visit https://aka.ms/wsl2

Install Linux kernel update

    cd $env:temp
    $progressPreference = 'SilentlyContinue'
    invoke-webRequest -uri https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi -outFile WSLUpdate.msi -useBasicParsing
rem invoke-webRequest -uri https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi                        -useBasicParsing

rem msiexec /package WSLUpdate.msi     /quiet
    msiexec /package WSLUpdate.msi     /passive
rem msiexec /package wsl_upate_x64.msi /quiet

Reset password

In Windows (not Linux!) command line
C:\users\rene> debian config --default-user root
C:\users\rene> debian
root@DESKTOP-1SDJMCL:~# passwd rene
…
root@DESKTOP-1SDJMCL:~# exit
C:\users\rene> debian config --default-user rene
Replace debian with the name of the distro for which the password needs to be reset.

Starting a distribution

The parameter -d of wsl specifies the distribution to be started. (The distribution must have been installed beforehand)
C:> wsl -d Debian
Alternatively, a distribution can be started like so:
C:\> kali

Accessing the «other» filesystem

DrvFS

DrvFs is a filesystem that allows WSL to mount NTFS and ReFS volumes.
DrvFS provides the following mount options:
uid User ID of the owner of the mounted files.
gid Group ID of the group-owner of the mounted files.
umask
fmask
dmask
metadata If set, Linux file permissions are stored in metadata of mounted files
case Case sensitivity of directory(?) names

Accessing the Windows Filesystem from WSL

With DrvFS, a Windows drive is (typically) mounted to /mnt/<drive> (the root of the default mount path can be changed with the root setting under [automount] in /etc/wsl.conf):
$ ls /mnt/c
$ ls /mnt/d
…
A newly plugged in external harddisk can be mounted within WSL like so. The following example assumes that the mounted files need to be accessible by the user whose id is 1000 and corresponding group id is also 1000:
$ sudo mkdir /mnt/e
$ sudo mount -t drvfs E: /mnt/e -o uid=1000,gid=1000,fmask=133,dmask=022
TODO: Should the mount options (specified with -o) be
$ sudo mount -t drvfs E: /mnt/e -o uid=1000,gid=1000,fmask=177,dmask=077

Accessing WSL Filesystem from Windows

In the explorer, the installed WSL filesystem can be accessed via \\wsl$\… or \\wsl.localhost\….
It's thus possible to map a network drive to a running WSL instance:
C:\> net use L: \\wsl$\Debian
The command completed successfully.

C:\> L:
L:\> dir
…
2020-09-03  01:56 AM    <DIR>          bin
2020-07-10  11:04 PM    <DIR>          boot
2022-06-01  12:41 AM    <DIR>          dev
2022-06-01  12:30 AM    <DIR>          etc
…
L:\> cd etc
L:\> notepad wsl.conf
This mapping is possible because the WSL client runs a 9P protocol file server for which the Windows host s a client (See for example the output of dmesg | grep 9p).
The communication between WSL and Windows runs over AF_UNIX sockets.

Networking

Starting from Windows 11 22H2 and WSL 2.0.9 or later, Windows firewall rules will by default apply to WSL (but see also configuring Hyper-V firewalls).

TCP/IP connections between the WSL guest and the host

From the host or network to the guest

The IP address(es) of the WSL guest can be obtained from within WSL in a shell like so:
$ hostname -I
172.31.17.20 172.18.0.1 172.17.0.1 172.19.0.1 172.20.0.1
These IP addresses can be accessed from the host, for example by accessing a webserver with https://172.31.17.20:8080/.

From the guest to the host

$ ip route show | grep -i default | awk '{ print $3}'
172.31.16.1

Accessing an USB device

WSL cannot natively access a USB device, but (with WSL 2 only?), it's possible with usbipd-win.

Prepare Kernel

In order to be able to mount an USB device, the kernel must be compiled with Mass USB enabled (by setting config optition CONFIG_USB_STORAGE to y) because the default WSL kernel also does not have support for USB storage device.
$ scripts/config --enable USB_STORAGE

Install usbip on the WSL guest

On the WSL guest, usbip must be installed (for example when running Debian or Ubuntu):
$ sudo apt install -y usbip usbutils hwdata

Install usbipd on the Host

On Windows (the host), usbipd (usbip-daemon) must be installed. This tools comes with
  • A service called usbipd (display name: USBIP Device Host).
  • A command line tool, also named usbipd. The location of this tool (C:\Program Files\usbipd-win) will be added to the PATH environment variable.
  • A firewall rule, again called usbipd, to allow all local subnets to connect to the service. This firewall rule can be modified to fine tune access control. (If using a third-party firewall, you may have to reconfigure it to allow incoming connections on TCP port 3240.)
usbipd-win can be installed with the following command line (which requires elevated privileges at one point)
C:\> winget install dorssel.usbipd-win
Winget tells to in reboot Windows, but as far as I can tell this is only to make sure that PATH is updated so that it contains usbipd.exe.
The result of the following commands indicate that the installation is ok:
PS C:\> (get-service usbipd).status
Running

PS C:\> netsh advfirewall firewall show rule name=usbipd | select-string Enabled
Enabled:                              Yes

PS C:\> & "C:\Program Files\usbipd-win\usbipd.exe" list
…
Then, list the USB devices attached to the host:
C:\> usbipd list
BUSID  VID:PID    DEVICE                                                        STATE
1-3    abcd:1234  USB-Massenspeichergerät                                       Not attached
1-8    04f2:b67c  Integrated Camera, Integrated IR Camera                       Not attached
Binding a USB-ID shares the USB device:
C:\> usbipd bind --busid=1-3
It can now be attached to WSL;
C:\> usbipd attach --wsl --busid=1-3
usbipd: info: Using WSL distribution 'Debian' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Using IP address 172.31.16.1 to reach the host.
Note: usbipd attach requires elevated privileges.
An attached USB device can be detached with usbipd detach ….

Again in WSL

Now, in WSL:
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID abcd:1234 LogiLink UDisk flash drive                         <<<< this one was added
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
The inserted USB device can finally be mounted:
$ sudo mkdir /mnt/usb
$ sudo mount /dev/sdd1 /mnt/usb
$ ls /mnt/usb
…

TODO

Uh oh:
$ sudo mount /dev/sdf1  /mnt/f
mount: /mnt/f: unknown filesystem type 'ntfs'.

$ cat /proc/filesystems

Interoperability

Interoperability allows to execute Windows and Linux binaries from both, a Windows command terminal or a Linux shell.
wsl.exe allows to run Linux binaries from the Windows Command Prompt (cmd.exe, PowerShell):
C:\> wsl ls -l
Thus, it is possible, for example, to update a WSL distribution when being in Windows:
C:\> wsl sudo apt-get update
The output of a Linux command executed via WSL can be piped to a Windows binary:
C:\> wsl ls -1 | findstr /i xyz
On the other hand, it is also possible to execute Windows bineries from WSL:
$ /mnt/c/Windows/explorer.exe
Interoperability can be enabled/or disabled:
echo 0 > /proc/sys/fs/binfmt_misc/WSLInterop
…
echo 1 > /proc/sys/fs/binfmt_misc/WSLInterop
A Windows executable that is started from WSL runs with the permissions of the user that ran wsl.exe.
DriveFS is a file system that makes interoperability possible.

Environment variables

Some aspects of WSL are controlled by a few environment variables.

$WSL_DISTRO_NAME

A shell started with wsl defines the environment variable $WSL_DISTRO_NAME whose value corresponds to the running Linux distribution.
For example, when stared in cmd.exe:
C:\> wsl -d kali-linux -- echo $WSL_DISTRO_NAME
kali-linux
Or in PowerShell (note the backtick to escape the special meaning of the dollar symbol in PowerShell):
PS C:\> wsl -d Debian -- echo `$WSL_DISTRO_NAME
Debian

$WSL_INTEROP

See /run/WSL

$WSLENV

WSLENV controls how (other) environment variables flow between WSL and Win32.

PULSE_SERVER

The value of PULSE_SERVER is /mnt/wslg/PulseServer.

Registry

Some information about the WSL installation is stored in the registry under the keys:

Enabling systemd

systemd can be enabled by adding systemd=true under the [boot] section of /etc/wsl.conf.
On a WSL distribution without enabled systemd, I observe the following:
$ ps -o cmd= 1
/init

$ ls -d /run/systemd
ls: cannot access '/run/systemd': No such file or directory
This is on a distribution where systemd is enabled:
$ ps -o cmd= 1
/sbin/init

$ file /sbin/init
/sbin/init: symbolic link to /lib/systemd/systemd

$ ls -d /run/systemd
/run/systemd

Compile a new Kernel

Install required tools
sudo apt install -y git
sudo apt install -y bc
sudo apt install -y build-essential
sudo apt install -y flex                 # required for example for scripts/kconfig/lexer.lex.c
sudo apt install -y bison                # bison -o scripts/kconfig/parser.tab.c --defines=scripts/kconfig/parser.tab.h -t -l scripts/kconfig/parser.y
sudo apt install -y libssl-dev
sudo apt install -y libelf-dev
sudo apt install -y dwarves              # for pahole and creation of .tmp_vmlinux.btf?
$ git clone --depth 1 https://github.com/microsoft/WSL2-Linux-Kernel
$ cd WSL2-Linux-Kernel
$ cp Microsoft/config-wsl .config
The copied .config file enables (quite possibly among others) the config symbol HYPERV:
$ grep CONFIG_HYPERV= .config
CONFIG_HYPERV=y
When I tried to build the Kernel (version WSL 5.15) with the copied .config file, I encountered the error message: FAILED: load BTF from vmlinux: No such file or directory.
I could solve this by commenting the config option CONFIG_DEBUG_INFO_BTF in the .config file.
Update 2023-12-15 (WSL 5.15.133): This step did not seem to be necessary anymore.
Playing Youtube movies in Chrome resulted in choppy audio on a ThinkPad notebook.
This comment suggested to set the config symbol CONFIG_HZ_1000 to y and then recompile the Kernel to solve the issue:
$ scripts/config --enable HZ_1000
Similarly, in order to be able to mount an USB device, the config option CONFIG_USB_STORAGE must be set to y.
$ make oldconfig
Building the Kernel:
$ make -j$(nproc)
The new Kernel can then be copied to the WSL host:
$ WINUSER=Rene
$ bzImageName=bzImage-chopy-audio
$ cp arch/x86_64/boot/bzImage /mnt/c/Users/$WINUSER/$bzImageName
It's necessary to tell the host where the new Kernel is located:
$ echo "[wsl2]
kernel=C:\\\\Users\\\\$WINUSER\\\\$bzImageName
" > /mnt/c/Users/$WINUSER/.wslconfig
Finally, the new kernel can be started by shutting down and restarting wsl:
C:\> wsl --shutdown
C:\> wsl

TODO: Alternative building commands

As per an answer I got on this issue, the kernel can alternatively be built with
$ sudo apt install -y build-essential flex bison dwarves libssl-dev libelf-dev bc
$ make KCONFIG_CONFIG=Microsoft/config-wsl

Win API

There are some WSL related functions in the WinAPI. These are declared in <wslapi.h>.

Misc

/etc/hosts inherits the entries from %windir%\system32\drivers\etc\hosts.
wslpath performs WSL/Windows path conversions:
$ wslpath C:/Users/Rene
/mnt/c/Users/Rene

$ wslpath -w /mnt/c/Users/Rene/
C:\Users\Rene

$ wslpath -m /mnt/c/Users/Rene/
C:/Users/Rene

Installation of Chrome in Debian/Ubuntu

curl does not seem to be installed, therefore, downloading the .deb file with wget:
# curl https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -o /tmp/chrome.deb
$ wget   https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -O /tmp/chrome.deb
$ sudo apt -y --fix-broken install /tmp/chrome.deb
This installs Chrome, but sound is missing

Better fonts

A few times after installing Debian, I found fonts to be crappy (especially in the URL bar) - but I have also had some problems with monospace fonts in both Chrome and gvim.
I was somehow able to mitigate the problems by installing fonts-noto:
$ sudo apt install -y fonts-noto
Installing fontos-noto improved fonts in Chrome's URL bar, but Monospace in was unreadable and Chrome.
I could solve the monospace font problem in Chrome by going to chrome://settings/fonts and then scrolling down to Fixed-width font and replacing Monospace with Liberation Mono.

No sound

A few times, I had no sound. Installing pavucontrol fixed this, too:
$ sudo apt install -y pavucontrol

Failed to configure network (networkingMode Nat). To disable networking, set `wsl2.networkingMode=None` in C:\Users\Rene\.wslconfig

After updating Windows, I couldn't start WSL anymore, the error message being:
Failed to configure network (networkingMode Nat). To disable networking, set `wsl2.networkingMode=None` in C:\Users\Rene\.wslconfig
Error code: Wsl/Service/CreateInstance/CreateVm/ConfigureNetworking/HNS/0x80070424

[process exited with code 4294967295 (0xffffffff)]
You can now close this terminal with Ctrl+D, or press Enter to restart.
Failed to configure network (networkingMode Nat). To disable networking, set `wsl2.networkingMode=None` in C:\Users\Rene\.wslconfig
Error code: Wsl/Service/CreateInstance/CreateVm/ConfigureNetworking/HNS/0x80070424

[process exited with code 4294967295 (0xffffffff)]
You can now close this terminal with Ctrl+D, or press Enter to restart.
I was able to start WSL again by going to Start menu, searching for Turn Windows features on or off and then enabling Virtual Machine Platform (also referred to as VPM).

Kernel modifications

One of the kernel modifications in the sources is the addition of the drivers/hv/dxgkrnl directory.

TODO

wsl --install --no-distro

This tweet suggests:
wsl --install --no-distro
Restart the machine.
wsl --import <yourDistro>
A small distribution to import is Alpine Linux.

No sound

Attempt one

ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
sudo apt install libpulse0
Possibly also?
sudo apt install libjack-jackd2-0

Attempt two

In a WSL 2 Debian installation, I had sound in Chrome, but when trying use a Csound frontend (blue, csoundqt), these were mute. csoundqt issued this error message PortAudio V19.6.0-devel, … error: No sound device is available … closing device and Failed to initialize real time audio output.
After installing the following package and restarting the WSL distro, I had sound for both, Chrome and csound frontends:
sudo apt-get install libasound-dev

GPU

The KConfig file in drivers/hv has an interesting note:
When WSL is instantiated, the Windows host assigns compatible host GPU adapters to the container.
The corresponding virtual GPU devices appear on the PCI bus in the container. These devices are enumerated and accessed by this driver.
Communications with the driver are done by using the Microsoft libdxcore library, which translates the D3DKMT interface to the driver IOCTLs (apparently exposed via /dev/dxg). The virtual GPU devices are paravirtualized, which means that access to the hardware is done in the host. The driver communicates with the host using Hyper-V VM bus communication channels.
Intel drivers can be downloaded from here (Download center)
AMD drivers can be downloaded from here.
Does the existence of /usr/lib/wsl/lib/libcuda.so.1 indicate that the GPU driver was installed on the host?
And what about /usr/lib/wsl/lib/nvidia-smi?

GPU selection in WSLg

This article describes how or which GPU is selected by MESA when running agaings WSLg's d3d12 backend.
Two key take aways of this article for me were:
  • Newer versions of MESA with the d3d12 backend choose the first enumerated integrated GPU.
  • The environment variable MESA_D3D12_DEFAULT_ADAPTER_NAME can be set to a substring of the name of the GPU that should be selected
  • glxinfo -B shows which GPU is currently used

Diagnosis of problems

$ glxinfo -B
$ glxinfo -B | grep -P 'OpenGL renderer string|Device:'
$ nvidia-smi
$ nvidia-smi -L
$ dmesg | grep dxg

Developer mode

It seems that developer mode was needed (but is not anymore) to enable the WSL.

Change display language of WSL

$ sudo update-locale LANG=en_US.UTF8

Pico Processes

Pico Processes are the foundation of WSL. (See also DrawBridge)

System Calls (syscalls)

lxcore.sys / lxss.sys

This provider is implemented by lxss.sys and lxcore.sys: they coordinate such syscall requests with the Windows NT Kernel.
When the NT Kernel is called with a syscall, the kernel checks if the call came from a pico process by checking the state in the process structure (I assume that to be a special flag).
If this is the case, the kernel saves the register state and «forwards» the call to the pico driver. The pico driver then finds the Linux syscall number in the RAX register and acts accordingly.
After having serviced the request, the calling flow is returned to the NT kernel which restores the register state and puts the return value into the RAX register.
Finally, the execution is returned to the WSL process.
A syscall is forwarded to lxcore.sys (or lxss.sys?) which either (preferrably) dispatches it to an NT syscall or handles it itself.
An example of a nice mapping between a Linux and NT syscall is sched_yield() and ZwYieldExecution().
On the other hand, fork() has no direct equivlent on NT. Therfore, when lxcore.sys (or lxss.sys?) handles a fork() call, it prepares the copying of the process, then calls the NT syscall to create a process and finally finishes the copying.
See also the WSL Blog: WSL System Calls.

File Systems

WSL comes with two file systems:
VolFS Cannot be used for interoperability. Provides most features of Linux VFS: permissions, sym-links, FIFOs, sockets and device files. VolFS is used to mount the root file system to /.
DriveFS Used for interoperability. File names are required to be valid Windows file names and are case insensitive. Windows drives (C:\ etc.) are mounted to /mnt/c etc.).

\Device\lxss

WSL creates the device object (kernel object?) \Device\lxss, verify with Winobj.exe

CreateLxProcess

CreateLxProcess() is apparently a COM method to talk to the LXSS Manager service.
This method is used by bash.exe.

LxBus

LxBus provides a channel, based on sockets, on which NT and WSL processes can communicate by exchanging messages and sharing state.
This channel is primarily used by the LXSS Manager service (NT) and /init (WSL).
LxBus is accessed (from the WSL) side by opending the /dev/lxss device (which is not shown with ls /dev/lxss). /dev/lxssclient supports a subset of /dev/lxss.

/init

/init is mapped from %SYSTEMROOT%\System32\lxss\tools\init which can be demonstrated like so:
$ diff  /init  /mnt/c/Windows/System32/lxss/tools/init
Update 2024-01-09: On the current environment, this diff command now reports a difference.
This reddit thread has the following interesting comment:
The '/init' executable in WSL2 distros is inserted at runtime by WSL2. It is not shipped by each distro. This executable has multiple functions and will appear several times in the process list while you are running the distro.
… there are at least these responsibilities: • run as pid1 to bootstrap the distro when starting it up including setting up wsl specific features, • Marshall interop calls between wsl and windows, • act as a plan 9 file server to share your windows file system with windows, • act as an entry point for binfmt_misc to execute windows binaries via interop.

See also

Installing a WSL Distribution on an external harddisk
%SYSTEMROOT%\System32\lxss
wslapi.dll
%USERPROFILE%\.wslconfig, /etc/wsl.conf
/run/WSL, /usr/lib/wsl
/etc/ld.so.conf.d/ld.wsl.conf
Running ps in WSL
C:\Users\\AppData\Local\Microsoft\WindowsApps\MicrosoftCorporationII.WindowsSubsystemForLinux_8wekyb3d8bbwe
wsl-screenshot-to-clipboard is use to copy a screenshot made with SnippingTool.exe into the clipboard using xclip.
The presence of /proc/sys/fs/binfmt_misc/WSLInterop is a pretty good indicator that a Kernel is running in WSL.

Links

Anderson Gama's blog was quite helpful to demonstrate how the kernel can be installed from the command line.
https://wiki.ubuntu.com/WSL has some hints on using WSL 2 and also has links to X Servers that can be used with WSL.
One of the most helpful resources for me to learn some details about WSL were the release notes.
Eliran Wong's notes (a Github repository).
VMCreate.exe allows to quickly install a Windows 11 dev environment which comes with WSL 2 and an Ubuntu installation.

Index