Introduction

WSL 2 on Windows 10 introduced the ability to run a native linux kernel on your computer while using Windows 10 as your main operating system. Instead of emulating a linux kernel, like WSL 1 does, WSL 2 uses a hypervisor to run linux in parallel with Windows.

To be able to run WSL 2 on Windows 10 a recent build with version 1903 or higher is required. WSL 2 was initially limited to version 2004 and above, but it has now been backported to 1903. For some time before that a Windows Insider Preview build was required to achieve this. This is not required anymore.

The official setup instructions, which this guide follows, are located under Windows Subsystem for Linux Installation Guide for Windows 10.

Windows Subsystem for Linux (WSL) 2 support

Open an administrator PowerShell by pressing Windows + X, then A or select PowerShell (Run as Administrator) from the start menu. Execute the following commands to enable the hypervisor to start on system boot.

# Enable WSL components for WSL 1
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

# Enable Hyper-V for WSL 2 (Additional requirement for WSL 2 support)
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Bug

    Enabling Hyper-V breaks VirtualBox 6.x.x!
    VirtualBox 7.0.2+ seems to work fine with Hyper-V.

Update VirtualBox 7.0.2 (03.11.2022):

    VirtualBox 7.0.2 on Windows 10 21H2 (Build 19044) works!

    The Virtual Machine does run and survived a full update from
    Ubuntu 21.04 to 22.04. (Except the update for Firefox broke
    due to the broken snap migration. But that's an Ubuntu
    thing I guess.)

Update VirtualBox 6.1.32 (24.01.2022):

    Using VirtualBox 6.1.32 on Windows 10 21H2 (Build 19044)
    the Virtual Machine does run but locks up frequently
    for minutes at a time.

    Linux Kernel Message:
      BUG: soft lockup - CPU#12 stuck for 23s! [snapd:1461]
      rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
      rcu: 12-...: (2223 ticks this GP) idle=c26/1/0x400000 ...
        softirq=1809/1809 fqs=5019
      ...

Update VirtualBox 6.1.28 (30.10.2021):

    Using VirtualBox 6.1.28 on Windows 10 21H2 (Build 19044)
    the Virtual Machine does not run at all.

    Error message: Call to NEMR0InitVMPart2 failed:
    VERR_NEM_INIT_FAILED (VERR_NEM_VM_CREATE_FAILED).

    Windows 10 21H2 seems to be the last major update for Windows 10.
    Therefore, WSL + VirtualBox might stay broken forever on Windows 10.

Update VirtualBox 6.1.20 (27.04.2021):

    Using VirtualBox 6.1.20 on Windows 10 21364
    the Virtual Machine does not run at all.

    Error message:
    Failed to get device handle and/or partition ID for 0000000001473d20
    (hPartitionDevice=0000000000000a9d, Last=0xc0000002/1)
    (VERR_NEM_VM_CREATE_FAILED).

Update VirtualBox 6.1.16 (13.11.2020):

    Using VirtualBox 6.1.16 on Windows 10 20251
    the Virtual Machine does not run at all.

    Error message:
    Failed to get device handle and/or partition ID for 0000000001aa7150
    (hPartitionDevice=0000000000000cd8, Last=0xc0000002/1)
    (VERR_NEM_VM_CREATE_FAILED).

Update VirtualBox 6.1.12 to 6.1.14 (16.09.2020):

    Using VirtualBox 6.1.12 the Virtual Machine runs way smoother.

    However, trying a sample installation (did not complete due to bugs)
    of Ubuntu shows that VirtualBox with Hyper-V enabled is still buggy.
    See bug 1874662 as an example bug I encountered.

Update VirtualBox 6.1.4:

    VirtualBox 6.1.4 works again with Windows 10 19564,
    but it runs unusable slow and crashes frequently.

The option VirtualMachinePlatform will break all your VirtualBox VMs while it is activated. To disable this setting, to be able to use VirtualBox again, run the following command.

Disable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Reboot your PC after changing the hypervisor settings!

Open an administrator command prompt / PowerShell and run the command wsl.exe --help to check if a new WSL version is running on your system. If you are running WSL 2 the option / flag --set-version should be listed in the program output.

Installation of the Gentoo userspace

Download the latest stage 3 build from the gentoo website (https://gentoo.org/downloads/). Select the profile which suits your needs. In my case I decided to use the most up-to-date, non-hardened, no-multilib, openrc, amd64 stage3 build (stage3-amd64-nomultilib-openrc-20211024T170536Z.tar.xz).

Quick-Link to index: current-stage3-amd64-nomultilib-openrc

  • non-hardened: This is only a development system, so no hardening is needed.
  • no-multilib: Who needs x86 support anyway when compiling from source?
  • openrc: Alternative to systemd. WSL doesn't require the init system anyway.
  • amd64: Because an up-to-date Windows 10 should be running on an up-to-date amd64 plaform.

Convert the tar.xz archive into an uncompressed tar archive by opening it with 7-Zip and selecting the extract option from the menu. Do not extract the linux filesystem packed in the tar archive.

Open an administrator command promt / PowerShell by pressing Windows + X, then A or select PowerShell (Run as Administrator) from the start menu. Run the following command to import the userspace image into your WSL configuration. Be sure that you provide full paths and didn't forget the --version argument. The destination path can be adjusted to your liking and is preferably on an SSD with at least 25 GB of free space. The import command will create a single virtual disk image (ext4.vhdx) in the destination folder.

wsl.exe --import "Gentoo" "D:\path\to\your\installation\directory" "C:\path\to\your\folder\stage3-amd64-nomultilib-openrc-20211024T170536Z.tar.xz" --version 2

If you forgot the --version switch, the result of the command above is an extracted linux filesystem in the specified Windows folder. Remove the distribution with wsl --unregister and restart the import operation.

Windows Terminal setup

Install the Windows Terminal (Preview) app from the Microsoft Store or go the the Microsoft Terminal Releases (https://github.com/microsoft/terminal/releases) page on github.com and download the msixbundle file. This terminal has tab support and a better intergration with WSL 2 than the standard command prompt.

When opening the Windows Terminal app a "Gentoo" option should be available from the tab dropdown menu. If the WSL 2 entry is not shown in the list continue below.


Changing the Gentoo option displayed in the Windows Terminal app

Click on the menu dropdown, then on settings. An editor (notepad) with the configuration file should be launched. To apply changes to the configuration save the file. The app should automatically apply the new configuration options without requiring a restart.

Below is an example configuration. Be sure to not change the GUID of the WSL configuration entry. Adjust the starting directory to your liking or omit the option when the default (Windows user home directory) is prefered. Terminal Version 0.11 comes with an updated configuration layout. See the Github Issue for migration tips. Delete the content of the file if you want to recreate all settings.

// This file was initially generated by Windows Terminal 0.11.1121.0
// It should still be usable in newer versions, but newer versions might have additional
// settings, help text, or changes that you will not see unless you clear this file
// and let us generate a new one for you.

// To view the default settings, hold "alt" while clicking on the "Settings" button.
// For documentation on these settings, see: https://aka.ms/terminal-documentation
{
    "$schema": "https://aka.ms/terminal-profiles-schema",

    "defaultProfile": "{1d2d9f1c-0192-5285-8115-38593c2c526e}",

    // You can add more global application settings here.
    // To learn more about global settings, visit https://aka.ms/terminal-global-settings

    // If enabled, selections are automatically copied to your clipboard.
    "copyOnSelect": false,

    // If enabled, formatted data is also copied to your clipboard
    "copyFormatting": false,

    // A profile specifies a command to execute paired with information about how it should look and feel.
    // Each one of them will appear in the 'New Tab' dropdown,
    //   and can be invoked from the commandline with `wt.exe -p xxx`
    // To learn more about profiles, visit https://aka.ms/terminal-profile-settings
    "profiles":
    {
        "defaults":
        {
            // Put settings here that you want to apply to all profiles.
            "acrylicOpacity" : 0.85000002384185791,
            "closeOnExit" : true,
            "colorScheme" : "Campbell",
            "cursorColor" : "#FFFFFF",
            "cursorShape" : "bar",
            "fontFace" : "Consolas",
            "fontSize" : 12,
            "historySize" : 9001,
            "padding" : "0, 0, 0, 0",
            "snapOnInput" : true,
            "startingDirectory": "C:\\wherever\\your\\projects\\are\\located\\",
            "useAcrylic" : true
        },
        "list":
        [
            {
                "guid": "{1d2d9f1c-0192-5285-8115-38593c2c526e}",
                "hidden": false,
                "name": "Gentoo",
                "source": "Windows.Terminal.Wsl"
            },
            {
                // Make changes here to the powershell.exe profile.
                "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
                "name": "Windows PowerShell",
                "commandline": "powershell.exe",
                "hidden": false
            },
            {
                // Make changes here to the cmd.exe profile.
                "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
                "name": "Commandline",
                "commandline": "cmd.exe",
                "hidden": false
            },
            {
                "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
                "hidden": false,
                "name": "Azure Cloud Shell",
                "source": "Windows.Terminal.Azure"
            }
        ]
    },

    // Add custom color schemes to this array.
    // To learn more about color schemes, visit https://aka.ms/terminal-color-schemes
    "schemes": [],

    // Add custom keybindings to this array.
    // To unbind a key combination from your defaults.json, set the command to "unbound".
    // To learn more about keybindings, visit https://aka.ms/terminal-keybindings
    "keybindings":
    [
        // Copy and paste are bound to Ctrl+Shift+C and Ctrl+Shift+V in your defaults.json.
        // These two lines additionally bind them to Ctrl+C and Ctrl+V.
        // To learn more about selection, visit https://aka.ms/terminal-selection
        { "command": {"action": "copy", "singleLine": false }, "keys": "ctrl+c" },
        { "command": "paste", "keys": "ctrl+v" },

        // Press Ctrl+Shift+F to open the search box
        { "command": "find", "keys": "ctrl+shift+f" },

        // Press Alt+Shift+D to open a new pane.
        // - "split": "auto" makes this pane open in the direction that provides the most surface area.
        // - "splitMode": "duplicate" makes the new pane use the focused pane's profile.
        // To learn more about panes, visit https://aka.ms/terminal-panes
        { "command": { "action": "splitPane", "split": "auto", "splitMode": "duplicate" }, "keys": "alt+shift+d" }
    ]
}

{
    "$schema": "https://aka.ms/terminal-profiles-schema",
    "globals":
    {
        "alwaysShowTabs" : true,
        "defaultProfile" : "{3996f19d-bc26-4ad0-aa38-292892098c1e}",
    },
    "profiles":
    [
        {
            "acrylicOpacity" : 0.85000002384185791,
            "closeOnExit" : true,
            "colorScheme" : "Campbell",
            "cursorColor" : "#FFFFFF",
            "cursorShape" : "bar",
            "fontFace" : "Consolas",
            "fontSize" : 12,
            "guid": "{3996f19d-bc26-4ad0-aa38-292892098c1e}",
            "hidden": false,
            "historySize" : 9001,
            "name": "Gentoo",
            "padding" : "0, 0, 0, 0",
            "snapOnInput" : true,
            "source": "Windows.Terminal.Wsl",
            "startingDirectory" : "C:\\wherever\\your\\projects\\are\\located\\",
            "useAcrylic" : true
        }
    ]
}

Old configuration style: Adjust the commandline to match your distribution name. You can use a GUID generator to generate the GUID for your profile.

{
    "$schema": "https://aka.ms/terminal-profiles-schema",
    "globals":
    {
        "alwaysShowTabs" : true,
        "defaultProfile" : "{3996f19d-bc26-4ad0-aa38-292892098c1e}",
    },
    "profiles":
    [
        {
            "acrylicOpacity" : 0.85000002384185791,
            "closeOnExit" : true,
            "colorScheme" : "Campbell",
            "commandline" : "wsl.exe -d Gentoo",
            "cursorColor" : "#FFFFFF",
            "cursorShape" : "bar",
            "fontFace" : "Consolas",
            "fontSize" : 12,
            "guid" : "{3996f19d-bc26-4ad0-aa38-292892098c1e}",
            "historySize" : 9001,
            "icon" : "ms-appx:///ProfileIcons/{3996f19d-bc26-4ad0-aa38-292892098c1e}.png",
            "name" : "Gentoo",
            "padding" : "0, 0, 0, 0",
            "snapOnInput" : true,
            "startingDirectory" : "C:\\wherever\\your\\projects\\are\\located\\",
            "useAcrylic" : true
        }
    ]
}

WSL setup in Gentoo

As with every new piece of software, the configuration needs some changes on the WSL / Gentoo side to run smoothly. Run the following commands on the Gentoo instance to fix problems with a non-functional nameserver configuration and file system attributes on Windows drives.

#!/bin/bash
set -e -x

# Delete auto-generated files
rm /etc/resolv.conf || true
rm /etc/wsl.conf || true

# Enable changing /etc/resolv.conf
# Enable extended attributes on Windows drives
cat <<EOF > /etc/wsl.conf
[network]
generateResolvConf = false

[automount]
enabled = true
options = "metadata"
mountFsTab = false
EOF

# Use google nameservers for DNS resolution
cat <<EOF > /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF

Create a .wslconfig configuration file for WSL in the Windows user directory. This is necessary to set a maximum size limit of the RAM which WSL may consume. Sometimes the linux kernel uses a portion of the free memory as cache and therefore will start to "eat away" all RAM of the host system. This can be mitigated by setting the memory configuration option. Replace YOURUSERNAME with your Windows username in the script below.

#!/bin/bash
set -e -x

cat <<EOF > /mnt/c/Users/YOURUSERNAME/.wslconfig
[wsl2]
#kernel=
memory=8GB
#processors=
#swap=
#swapFile=
localhostForwarding=true
EOF

Now close all instances of Gentoo / WSL and stop the virtual machine by opening the Command Prompt (Windows-Key + X, then A) and issuing the command wsl --shutdown .

Gentoo setup in WSL

Run all following commands in the Gentoo instance.

For gentoo to work correctly under the hypervisor some feature flags have to be disabled. Open the file /etc/portage/make.conf and adjust the following settings. Below is an example configuration used for my system.

  • Add FEATURES="-ipc-sandbox -pid-sandbox -mount-sandbox -network-sandbox" to disbable the non-functional sandboxing features
  • Adjust COMMON_FLAGS to match your PC architecture.
  • Adjust USE to your needs
  • Ajdust MAKEOPTS to the number of CPU cores (+1) to make the compilation faster
  • The other options are all optional

# No GUI (-X -gtk), only english error messages (-nls)
USE="-X -gtk -nls"

# Enable python 3.7 and set 3.6 as default
PYTHON_TARGETS="python3_6 python3_7"
PYTHON_SINGLE_TARGET="python3_6"

# Define targets for QEMU
QEMU_SOFTMMU_TARGETS="aarch64 arm i386 riscv32 riscv64 x86_64"
QEMU_USER_TARGETS="aarch64 arm i386 riscv32 riscv64 x86_64"

# No hardware videocard support
VIDEO_CARDS="dummy"

# Disable non-functional sandboxing features
FEATURES="-ipc-sandbox -pid-sandbox -mount-sandbox -network-sandbox"

# Always ask when managing packages, always consider deep dependencies (slow)
EMERGE_DEFAULT_OPTS="--ask --complete-graph"

# Enable optimizations for the used CPU
COMMON_FLAGS="-march=haswell -O2 -pipe"
CHOST="x86_64-pc-linux-gnu"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
MAKEOPTS="-j5"

# NOTE: This stage was built with the bindist Use flag enabled
PORTDIR="/var/db/repos/gentoo"
DISTDIR="/var/cache/distfiles"
PKGDIR="/var/cache/binpkgs"

# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.
LC_MESSAGES=C

Final installation steps

To finish the Gentoo installation a new snapshot of the ebuild repository should be downloaded. A recompilation of the compiler ensures that GCC is on the most recent stable version. After updating GCC a recompilation of all programs / libraries ensures that the set optimizations take effect.

#!/bin/bash
set -e -x

# Download a snapshot of all official ebuilds
emerge-webrsync

# Upgrade the compiler and the required libtool library
emerge --oneshot --deep sys-devel/gcc
emerge --oneshot --usepkg=n sys-devel/libtool

# Update all packages with the newly built compiler
# This will take a long time, ~1-5 hours
emerge --oneshot --emptytree --deep @world
emerge --oneshot --deep @preserved-rebuild
emerge --ask --depclean

Gentoo workspace (docker, tmux, portage) setup

The next part describes how to configure portage, docker and tmux on the new Gentoo system. It can be found here: Finalizing the Gentoo installation

(Un-)License

This is free and unencumbered software released into the public domain.


Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.


In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


For more information, please refer to http://unlicense.org/