master
md 116 lines 6.88 KB
Rendered Raw
1 # The WSL2 boot process
2
3 This page describes the steps in the WSL2 process, from the user invoking [wsl.exe](wsl.exe.md) to the user's Linux shell (bash in this example), in the WSL2 distribution.
4
5 ## Overview
6
7 The below diagram shows the sequence of events to start bash within a WSL2 distribution. See [WSL architecture](index.md) for details about what each process does.
8
9 ```mermaid
10 sequenceDiagram
11 wsl.exe->>wslservice.exe: CreateInstance(<distro>)
12 wslservice.exe->>wsl.exe: S_OK
13 wsl.exe->>wslservice.exe: CreateLxProcess(<distro>, <command line>, <env>, ...)
14 create participant mini_init
15 wslservice.exe->>mini_init: LxMiniInitMessageEarlyConfig
16 create participant gns
17 mini_init-->>gns: fork(), exec("/gns")
18 wslservice.exe->>gns: LxGnsMessageInterfaceConfiguration
19 gns->>wslservice.exe: LxGnsMessageResult
20 wslservice.exe->>mini_init: LxMiniInitMessageInitialConfig
21 wslservice.exe->>mini_init: LxMiniInitMessageLaunchInit
22 create participant init
23 mini_init-->>init: fork(), exec("/init")
24 init->>wslservice.exe: LxMiniInitMessageCreateInstanceResult
25 wslservice.exe->>init: LxInitMessageCreateSession
26 create participant session leader
27 init-->>session leader: fork()
28 session leader->>wslservice.exe: LxInitMessageCreateSessionResponse
29 wslservice.exe->>session leader: InitCreateProcessUtilityVm
30 create participant relay
31 session leader-->>relay: fork()
32 relay->>wslservice.exe: LxMessageResultUint32 (hvsocket connect port)
33 wslservice.exe->>relay: connect hvsockets for STDIN, STDOUT, STDERR
34 create participant bash
35 relay-->>bash: fork(), exec("/bin/bash")
36 relay<<-->>bash: relay STDIN, STDOUT, STDERR
37 wslservice.exe-->>wsl.exe: S_OK + hvsockets for STDIN, STDOUT, STDERR
38 wsl.exe<<->>relay: Relay STDIN, STDOUT, STDERR
39 destroy bash
40 relay-->>bash: waitpid()
41 relay->>wsl.exe: LxInitMessageExitStatus (process exit code)
42 ```
43
44 ## CreateInstance()
45
46 When [wslservice.exe](wslservice.exe.md) receives the CreateInstance() call via COM, it will:
47
48 1) Identify which distribution the user wants to create. This is done by looking up the `DistributionRegistration` (see `src/windows/service/exe/DistributionRegistration.cpp`) in the Windows registry, matching either on the distribution ID, or using the default if none is provided.
49
50 2) Based on the type of distribution (WSL1 or WSL2), either create a WSL1 instance, or start up a WSL2 virtual machine.
51
52 3) Associate the newly creating distribution to the calling process (see `src/windows/service/exe/Lifetime.cpp`)
53
54
55 ## Starting the WSL2 virtual machine
56
57 To start a WSL2 distribution, [wslservice.exe](wslservice.exe.md) needs a virtual machine. If the virtual machine isn't already running, it will be created as part of the `CreateInstance()` call.
58
59 The WSL2 virtual machine is created via the [Host Compute System (HCS) service](https://learn.microsoft.com/virtualization/api/hcs/overview) (see `src/windows/service/exe/WslCoreVm.cpp`).
60
61 To create a new virtual machine, [wslservice.exe](wslservice.exe.md) generates a JSON string, which describes the virtual machine configuration. This JSON is then passed to [HcsCreateComputeSystem()](https://learn.microsoft.com/virtualization/api/hcs/reference/hcscreatecomputesystem) to create a new virtual machine.
62
63 See `src/windows/common/hcs_schema.h` for more details on the HCS JSON schema.
64
65 Part of the JSON configuration includes:
66
67 - The kernel: WSL will use its built-in kernel, usually installed in `C:\Program Files\WSL\tools\kernel`, or a custom kernel if overridden via [.wslconfig](https://learn.microsoft.com/windows/wsl/wsl-config)
68 - The initramfs: WSL uses its own initramfs (usually installed in `C:\Program Files\WSL\tools\initrd.img`). It's an image that only contains the [mini_init](mini_init.md) binary
69 - The resources accessible to the virtual machine such as CPU, RAM, GPU, etc
70
71 When started, the virtual machine will boot into the provided kernel, and then execute [mini_init](mini_init.md).
72
73 ## The Linux boot process
74
75 [mini_init](mini_init.md) is the process that performs usermode initialization inside the virtual machine. After performing various configurations, `mini_init` receives a `LxMiniInitMessageEarlyConfig` message from the [wslservice.exe](wslservice.exe.md) which contains the following information:
76
77 - Identifiers for the system VHD, swap VHD and kernel modules VHD if any
78 - The machine's hostname
79 - The configured memory reclaim mode and page reporting order
80
81 [mini_init](mini_init.md) then creates the [gns process](gns.md), which is responsible for networking configuration and then receives a `LxMiniInitMessageInitialConfig` message, which contains:
82
83 - An entropy buffer, to seed the virtual machine's entropy
84 - Information about the GPU drivers shares to mount, if any
85 - Whether [wslg](https://github.com/microsoft/wslg) is enabled
86
87 After applying all the configuration requested by [wslservice.exe](wslservice.exe.md), the virtual machine is ready to start Linux distributions.
88
89 ## Starting a Linux distribution
90
91 To start a new distribution, [wslservice.exe](wslservice.exe.md) sends a `LxMiniInitMessageLaunchInit` message to [mini_init](mini_init.md), which then mounts the distribution vhd and starts [init](init.md). See [init](init.md) for more details on WSL2 distributions configuration.
92
93 Once running, [wslservice.exe](wslservice.exe.md) can then send a `LxInitMessageCreateSession` message to start a new [session leader](session-leader.md) inside that distribution, which can be used to launch Linux processes
94
95 ## Relaying the Linux process's input and output to Windows
96
97 Once the user's Linux process has been created, [wslservice.exe](wslservice.exe.md) can return from `CreateLxProcess()` back to [wsl.exe](wsl.exe.md). In the case of WSL2, [wsl.exe](wsl.exe.md) receives the following HANDLES:
98
99 - STDIN
100 - STDOUT
101 - STDERR
102 - Control channel
103 - Interop channel
104
105 The `STDIN`, `STDOUT` and `STDERR` handles are used to relay input and output from the Linux process to the Windows terminal. Depending on the type of handle (terminal, pipe, file, ...), [wsl.exe](wsl.exe.md) will apply different relaying logics (see `src/windows/common/relay.cpp`) to achieve the best compatibility between Windows & Linux.
106
107 The `Control channel` is used to notify the Linux process of a change in the terminal (for instance when [wsl.exe's](wsl.exe.md) terminal window is resized) so these changes can be applied to the Linux process as well.
108
109 The `Interop channel` has two usages:
110
111 - Create Windows processes from Linux (see [interop](interop.md))
112 - Notify [wsl.exe](wsl.exe.md) when the Linux process has exited (see `LxInitMessageExitStatus`)
113
114 Once the Linux process has exited, [wsl.exe](wsl.exe.md) flushes all remaining IO, and exits with the same exit code as the Linux process.
115
116 If [wsl.exe](wsl.exe.md) is terminated before the Linux process exits, [wslhost.exe](wslhost.exe.md) will take over the `Interop channel` and continue to handle requests to execute Windows processes.