microsoft/WSL2-Linux-Kernel: building a custom WSL2 kernel
The source for the Linux kernel used in Windows Subsystem for Linux 2 (WSL2)
At a glance
- What is it?
- The WSL2-Linux-Kernel repository holds the kernel source and the Microsoft/config-wsl configuration that WSL2 boots. This is a build tree for people who need a kernel option the stock image does not ship, not a package you install to update WSL2.
- Who is it for?
- Adopt this tree if you need a kernel option the shipped WSL2 kernel does not enable and you are willing to build it on Ubuntu with build-essential, flex, bison and libelf-dev. Do not adopt it if you only want to update WSL2, since the repository README points updates and bug reports at the WSL GitHub project and the Linux kernel update package instead.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 60 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the WSL2 kernel tree is for, and who should build it
WSL2 runs a real Linux kernel inside a lightweight virtual machine, and that kernel is not the one your distribution ships. This repository carries the source and the configuration file, Microsoft/config-wsl, that Microsoft builds the WSL2 kernel from. The README describes it plainly as the source for the kernel used in WSL2. That framing matters: the default branch here is linux-msft-wsl-6.18.y, a Microsoft-maintained branch, and the latest release listed is linux-msft-wsl-6.18.40.1 from 2026-08-01. The last push to the repository was on 2026-08-01, so it is not abandoned, but it is also not a project that ships weekly.
The audience is narrow and specific. You are building this kernel if you need a config option, a driver, or a debug facility that the stock WSL2 kernel does not enable, and you want it inside your own WSL2 instance. If your goal is simply to keep WSL2 current, this is the wrong repository. The README routes bug reports and feature requests to the WSL GitHub project, and the install instructions point at the .wslconfig documentation for using a custom built kernel. The kernel update package people search for is a separate Microsoft download, not an artifact of this tree.
How the build works: config-wsl, modules, headers, perf, VHDX
The build is a normal Linux kernel build with one WSL-specific twist. Instead of .config, the make invocations pass KCONFIG_CONFIG=Microsoft/config-wsl, so the WSL2 configuration file is read and written in place. That file is the single point where the WSL2 kernel's feature set is defined, and it is also the file you edit with menuconfig when you want to change something.
The output is not a single kernel binary. WSL2 expects a VHDX image containing modules, UAPI headers, and the perf tooling laid out under a directory named after the kernel release. The README spells out the expected layout as <kernelrelease>/{modules,linux-headers,perf}. The provided script Microsoft/scripts/gen_artifacts_vhdx.sh takes the three built directories plus the release string and produces modules.vhdx. The manual path is longer: stage the three trees under the release directory, compute the image size from du plus 256MiB of slack, build an ext4 image with mke2fs, convert it with qemu-img to vhdx, then delete the intermediate image. Both routes end at the same artifact, and the release string is what ties the VHDX to the kernel you built, which is why the script takes $(make -s kernelrelease) as an argument.
The Makefile itself confirms the version this branch corresponds to: VERSION 6, PATCHLEVEL 18, SUBLEVEL 40, EXTRAVERSION .1, with the codename Baby Opossum Posse. It also requires GNU Make 4.0 or newer and errors out if output-sync is unavailable, which is a hard floor on the build host rather than a suggestion.
Installing the build dependencies and producing a first modules.vhdx
The README gives an x86_64 workflow on an Ubuntu distribution using bash. Start with the dependency list exactly as written, since the kernel build needs flex, bison, dwarves and libelf-dev, and the VHDX step needs qemu-utils.
sudo apt install build-essential flex bison dwarves libssl-dev libelf-dev cpio qemu-utils rsyncIf you need to change the configuration, menuconfig operates on the WSL2 config file rather than a default .config. The README shows the optional step as follows, and any change you make here is what distinguishes your kernel from the stock one.
make menuconfig KCONFIG_CONFIG=Microsoft/config-wslBuild the kernel and install the modules into a local modules directory. Adding -j$(nproc) to the first make, as the README suggests, is the difference between a long wait and a very long wait on a machine with many cores.
make KCONFIG_CONFIG=Microsoft/config-wsl && make INSTALL_MOD_PATH="$PWD/modules" modules_installInstall the UAPI headers and build perf into their own directories. The perf build disables several optional dependencies, which reduces what you need installed on the host.
make headers_install INSTALL_HDR_PATH="$PWD/headers"
make -C tools/perf NO_JEVENTS=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 install DESTDIR="$PWD/perf" prefix=/Finally, hand the three directories and the kernel release string to the provided script to get modules.vhdx. The README then suggests make clean and removing the modules, headers and perf directories to reclaim space.
./Microsoft/scripts/gen_artifacts_vhdx.sh "$PWD/modules" "$PWD/headers" "$PWD/perf" $(make -s kernelrelease) modules.vhdxWhat you should have at the end is a single VHDX file. Pointing WSL2 at it is done through .wslconfig, which the README defers to Microsoft's documentation for rather than describing here.
The manual VHDX path, and why the release string is the fragile part
The scripted route hides a layout contract that the manual instructions expose. WSL2 expects the artifacts under a directory named with the kernel release, so the staging step creates that directory and copies modules, headers and perf into it.
release=$(make -s kernelrelease)
mkdir -p "$PWD/staging/$release/linux-headers"
cp -r "$PWD/modules/lib/modules/$release" "$PWD/staging/$release/modules"
rm -f "$PWD/staging/$release/modules/build" "$PWD/staging/$release/modules/source"
cp -r "$PWD/headers/." "$PWD/staging/$release/linux-headers"
cp -r "$PWD/perf" "$PWD/staging/$release/perf"The two rm lines are not cosmetic. The modules_install step leaves build and source symlinks pointing into the build tree, and those paths will not exist inside the guest, so they are removed before imaging. The remaining steps compute the image size, create the ext4 filesystem with mke2fs, convert to VHDX with qemu-img, and remove the intermediate .img file.
image_size=$(du -bs "$PWD/staging" | awk '{print $1;}'); image_size=$((image_size + (256 * (1<<20))));
mke2fs -L '' -d "$PWD/staging" -N $(( $(find "$PWD/staging" | wc -l) + 4096 )) -b 1024 -t ext4 "$PWD/modules.img" $((image_size / 1024))
qemu-img convert -O vhdx "$PWD/modules.img" "$PWD/modules.vhdx"Everything here keys off $(make -s kernelrelease). If the release string you stage under differs from the one the kernel reports at boot, the guest looks in the wrong directory. Run the kernelrelease command in the same tree and with the same configuration you built with, and do not hand-type the version.
Where this repository stops: bugs, features and the missing install detail
The README is explicit that issues cannot be filed on this project. Bug reports go to the WSL GitHub project, and if you can show the bug exists upstream, the README points you at the separate processes for normal bugs and security bugs in the Linux kernel. Feature requests follow the same route, with an encouragement to submit the change upstream if you can write the kernel code yourself. That is a deliberate boundary: this tree is a downstream branch, and Microsoft does not run its issue tracker as the intake for WSL kernel problems.
The install side is where the documentation thins out. The README says to see the .wslconfig documentation for using a custom built kernel, and stops there. It does not document the .wslconfig keys, does not show a kernel= line, and does not describe rollback. If your custom kernel fails to boot, the recovery path is not in this repository. You are relying on Microsoft's separate WSL configuration documentation and on your ability to edit .wslconfig from Windows.
There is also no statement here about what Microsoft/config-wsl contains, which options are enabled, or how far it diverges from a defconfig. Reading the file is the only way to know, and that is a real cost when you are trying to decide whether a custom build is necessary at all.
When a custom WSL2 kernel is the wrong tool
Building this kernel is the wrong move if the option you want is already enabled in Microsoft/config-wsl. The configuration file is in the tree; check it before spending an hour on a build. It is also wrong if you are chasing general WSL2 performance, since nothing in this repository claims a performance advantage over the shipped kernel, and the README is silent on benchmarking.
The maintenance shape is the second reason to hesitate. The branch tracks a specific upstream line, currently 6.18.y, and the listed releases cluster: linux-msft-wsl-6.18.40.1 on 2026-08-01, and two releases on 2026-06-19. Every upstream point release you want to follow means a fresh build and a fresh VHDX. There is no upgrade mechanism in this repository, no package to install, and no delta update. You own the rebuild loop.
If your problem is that WSL2 itself is outdated, the answer is the kernel update package and the WSL distribution's own update path, not this tree. The searches that lead people here are mostly about updating WSL2, and this repository does not do that.
Alternatives: stock WSL2 kernel, distro kernels, and upstream Linux
The first alternative is doing nothing. WSL2 ships a kernel that Microsoft builds from this configuration, and it covers the common cases. If your workload runs under it, a custom build adds a VHDX file to maintain and a .wslconfig entry to keep correct for no gain.
The second is the upstream Linux kernel. The README itself suggests working with upstream developers when you can show a bug exists there, and it links the bug-hunting and patch-submission guides. The difference in approach is that upstream is where the change belongs if it is generally useful; this branch is where it lands for WSL2 specifically, and only after it goes through Microsoft's merge process. Note the MSFT-Merge directory at the top level, which is part of how that flow is organized.
A distribution kernel is not a substitute here. WSL2 boots its own kernel, not the one in your Ubuntu image, so installing a distro kernel package changes the guest distribution's modules but not what the VM boots. That distinction is the whole reason this repository exists, and it is the thing most likely to confuse someone arriving from a search for a kernel update.
Editorial conclusion
Adopt this tree if you need a kernel option the shipped WSL2 kernel does not enable and you are willing to build it on Ubuntu with build-essential, flex, bison and libelf-dev. Do not adopt it if you only want to update WSL2, since the repository README points updates and bug reports at the WSL GitHub project and the Linux kernel update package instead. Before committing, verify that Microsoft/config-wsl already lacks the option you need, that your .wslconfig kernel= path is correct, and that the kernelrelease string you built matches the release directory you staged.
Frequently asked questions
How do I manually install the kernel in WSL2?
The README does not give a manual install procedure. It says to see the .wslconfig configuration file documentation for information on using a custom built kernel, and the repository stops at producing a VHDX.
How do I update the Linux kernel in WSL2?
This repository is not the update path. It contains the kernel source and Microsoft/config-wsl, and the README directs bug reports and feature requests to the WSL GitHub project rather than offering an update mechanism.
What are the limitations of WSL2?
The README does not enumerate WSL2 limitations. What it does state is that issues relating to WSL or the WSL2 kernel must be reported on the WSL GitHub project, since the WSL2-Linux-Kernel project does not accept them.
What is the WSL2 Linux kernel?
It is the Linux kernel that WSL2 boots inside its virtual machine. This repository holds its source code and configuration files, and the current branch builds version 6.18.40.1.
install wsl2 linux kernel
The README's build instructions are the closest thing to an install path: install the build dependencies, build with KCONFIG_CONFIG=Microsoft/config-wsl, and produce a VHDX. Using that kernel is configured through .wslconfig, which the README points to Microsoft's documentation for.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-wsl2-linux-kernel)