Proton Kernel is a custom modified Linux kernel for the Windows Subsystem for Linux 2, using a clean import of Microsoft's kernel changes as a base. The goal is to improve performance, memory utilization, and power efficiency while reducing boot times and making other improvements to the overall user experience.
Microsoft did a relatively good job on their minimal set of changes to the Linux kernel in WSL 2, but there is always room for improvement. For example, one can compile the kernel with a newer version of GCC (Microsoft used a custom build of GCC 7.3.0) or even Clang. This can offer small performance improvements and help debug certain parts of both the kernel and the compiler.
Proton Kernel aims to improve upon Microsoft's kernel in every aspect and thus improve the overall WSL 2 user experience.
-
Install a recent Linux distribution
- Any install will work — WSL 1, WSL 2, VirtualBox, bare-metal, etc.
-
Install GCC or Clang, essential development packages,
flex
,bison
, OpenSSL + headers,libelf
+ headers- Example command for Ubuntu:
apt install build-essential flex bison libssl-dev libelf-dev
- Example command for Ubuntu:
-
Load the Proton Kernel helpers (optional)
- Note that this requires a Bourne-compatible shell, such as
bash
orzsh
- Command:
source setup.sh
for GCC orsource setup_clang.sh
for Clang - These helpers are solely to simplify the building and testing process and are not mandatory by any means
- Parallel Kbuild job count can be adjusted in the
setup
scripts- The optimal value for build times is usually the number of logical CPU cores present on your system
- Sometimes increasing or decreasing this number helps reduce build time further
- Note that this requires a Bourne-compatible shell, such as
-
Select the WSL 2 kernel configuration
- Using the Proton helpers:
mc
- Using plain Kbuild:
make wsl2_defconfig
- Using the Proton helpers:
-
Start the kernel build
- Using the Proton helpers:
kmake
- Using plain Kbuild:
make
- If you have multiple CPU cores, you can pass a
-jX
argument (whereX
is the number of logical CPU cores present on your system) to speed up the build by parallelizing the process - Sometimes increasing or decreasing this number helps reduce build time further
- If you have multiple CPU cores, you can pass a
- Using the Proton helpers:
Assuming there were no errors and everything worked as intended, you will find the new kernel at the following location:
- Using Proton helpers:
out/arch/x86/boot/compressed/vmlinux.bin
- Using plain Kbuild:
arch/x86/boot/compressed/vmlinux.bin
If not, double-check each command to make sure you did everything correctly. You can open an issue if you need help resolving a build error.
BE SURE TO MAKE A BACKUP OF THE OFFICIAL KERNEL PRIOR TO REPLACEMENT! Otherwise, you will be unable to revert if your custom kernel fails to boot or malfunctions.
Warning: Having any unofficial kernel installed currently breaks distribution installation and conversion for unknown reasons and causes the process to lock up. A temporary workaround is to use the official kernel for the aforementioned tasks, then revert back to your custom kernel afterwards.
The kernel is located at C:\Windows\System32\lxss\tools\kernel
in Windows.
When you first replace the WSL 2 kernel on your system, you will need to grant yourself the permissions necessary to replace the file. This requires administrator access.
-
Assign ownership of the
kernel
file to the Administrators group- This is easy to do in Windows Explorer:
- Right-click the file and click Properties
- Switch to the Security tab
- Click the Advanced button
- Click the blue Change button next to Owner
- Enter Administrators for the object name
- Click OK to close the advanced security window and reload permissions
- This is easy to do in Windows Explorer:
-
Grant Full Control of the file to Administrators and yourself
- Again, this is trivial in Windows Explorer:
- Return to the advanced security management window
- Click the Change permissions button
- Double-click Administrators in the list of permission entries and check the Full Control box
- Dismiss the entry control dialog
- Click the Add button to add a new permission entry
- Click the blue Select principal button at the top and enter your username at the object name prompt
- Check the Full Control box
- Dismiss the entry control dialog
- Again, this is trivial in Windows Explorer:
After taking ownership and acquiring critical permissions, you may proceed to the kernel replacement steps listed below. These preparatory steps may need to be repeated after each Windows update.
- Run the desired command(s) from the list below:
- Copy the product to
kernel.bin
:cpimg
- Build and copy:
incbuild
- Build, copy, and test:
inc
- Test:
ktest
- Copy the product to
Note that ktest
looks for kernel.bin
for ease of management, not the build product (out/arch/x86/boot/compressed/vmlinux.bin
). This means that you will need to either use incbuild
to build or run cpimg
after each build to copy the new kernel to kernel.bin
.
-
Shut down the WSL 2 distros and utility VM from Windows
- Command:
wsl --shutdown
- Command:
-
Rename the new kernel (
vmlinux.bin
) tokernel
-
Copy the new
kernel
toC:\Windows\System32\lxss\tools
and choose to overwrite the existing file namedkernel
Be sure to copy and overwrite the kernel. Doing otherwise (moving, deleting and recreating, etc.) will invalidate the hard link in WinSxS
, which may cause issues when updating or repairing the system in the future. You have been warned.
The Proton Kernel helper scripts provide a handy set of helpers that enhance the overall kernel development and deployment experience. You can use them in a Bourne-compatible shell by source
ing one of the compiler-specific setup scripts — source setup.sh
for GCC and source setup_clang.sh
for Clang. If you don't want to use one of those scripts, you can also directly run source helpers.sh
. However, this setup is not supported nor encouraged and may break at any time.
Keep in mind that you must source
the scripts instead of executing them. Nothing will happen if you execute them because they simply define variables and functions for interactive use. They are not build scripts. The execute bit is missing on them for this very reason.
croot
:cd
to the root of the kernel tree, where the helper scripts arecpimg
: Copy the product to the specified path, defaulting tokernel.bin
dimg
: Copy the product tobuilds
with a file name tailored for development/test releasestimg
: Rundimg
, then upload the resulting file to transfer.sh
kmake
: A wrapper formake
that passes the defined kernel-oriented argumentscleanbuild
: Perform a clean build and runcpimg
incbuild
: Perform an incremental build and runcpimg
dbuild
: Perform an incremental build and rundimg
tbuild
: Perform an incremental build and runtimg
rel
: Build and copy the product tobuilds
with a file name and version tailored for stable releasescrel
: Clean the built object files and runrel
ktest
: Installkernel.bin
using an auto-selected method (wktest
for WSL 1 and WSL 2,vktest
for other environments)wktest
: Installkernel.bin
locally from either WSL 1 or WSL 2vktest
: Installkernel.bin
into WSL 2 in the Windows VM running on a bare-metal Linux host (using thewinvm
SSH host)
inc
: Perform an incremental build and install the product using an auto-selected method (wktest
for WSL 1 and WSL 2,vktest
for other environments)winc
: Perform an incremental build and install the product locally from either WSL 1 or WSL 2vinc
: Perform an incremental build and install the product into WSL 2 in the Windows VM running on a bare-metal Linux host (using thewinvm
SSH host)
dc
:diff
the current config withwsl2_defconfig
cpc
: Updatewsl2_defconfig
with the current configmc
: Reset the current config towsl2_defconfig
cf
: Start an interactive config editor with a TUI (nconfig
)ec
: Open the raw current config in a text editorbuildnum
: Get the current build numberzerover
: Reset the build number to0
zver
: Get the version string from an uncompressed kernel imageosize
: Get a sorted list of the sizes of various objects compiled and linked into the final kernel imageglink
: Get a link to the provided commit hash in this repository on GitHub
All building helpers will propagate the arguments passed to them to make
.