This guide only mentions Arch Linux as it’s the only good alternative to building AOSP on besides Ubuntu. It utilises Docker Desktop for the Arch Linux image as it’s very close to stock Arch Linux instead of using tools like ArchWSL which are not very close to stock Arch Linux. Docker Desktop uses the official Arch Linux Docker image.
AOSP and GrapheneOS dependencies:
- At least 400GB of fast SSD (preferably NVMe) storage
- At least 20GB of DDR4 memory.
- At least a quad core processor
- python3-protobuf (python-protobuf on Arch)
- gpg (gnupg on Arch)
- libgcc (gcc-libs on Arch)
- ttf-liberation or any other TrueType/OpenType font
- ncurses5 (ncurses5-compat-libs on AUR)
- OpenJDK (jdk8-openjdk or jdk11-openjdk or jdk-openjdk for 17 on Arch)
Arch deps for WSLg and AOSP emulator:
WSL2 / WSLg dependencies:
- Windows 11 Professional (Enterprise preferred, Home will not work)
- Windows 11 supported hardware
- Intel VT-x or similar
- Intel VT-d or similar
- Up to date BIOS/UEFI
- Windows 11 installed with UEFI
- TPM 1.2 or 2.0
Open “Turn Windows features on or off”
- Virtual Machine Platform
- Windows Hypervisor Platform
- Windows Subsystem for Linux
- then reboot
Install the Linux kernel update package: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
Open PowerShell and update WSL:
Set WSL2 as the default version:
wsl --set-default-version 2
Docker Desktop setup:
Install Docker Desktop: https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe
During install, install the WSL components as it says.
Open Docker and if asked to install wsl_update_x64.msi again, install it again.
Make sure in Docker settings it’s using WSL backends.
Arch Linux Docker install:
Using PowerShell, pull the official Arch Linux image:
docker pull archlinux
Run the image with the name
archlinux-wslto setup the base image:
docker run -it --name archlinux-wsl archlinux
- Perform the following setup commands:
pacman -Syu pacman -S sudo vim EDITOR=vim visudo # uncomment wheel useradd -G wheel,users -m <username> passwd <username> # make a password pwconv grpconv # no output is expected # perform any extra setup yourself if you want as this is the base image exit
- Export the docker container’s state to a tar file:
docker export --output archlinux-image-files.tar archlinux-wsl
- Import the container files to a drive you have more than 500GB on (can be your C drive if you have that space):
wsl --import archlinux <directory to store the files> .\archlinux-image-files.tar
Verify Arch Linux is using WSL version 2:
wsl -l -v
Open Arch Linux:
wsl -d archlinux
Arch Linux post-install
The default Virtual Hard Disk (.vhdx) created is only 256GB as shown by
df -h. This is not enough for AOSP. We need to resize it (at this point I assume the drive you have the .vhdx file on is more than 500GB).
Shut down WSL:
Locate the .vhdx file from step 5 above and get the absolute path.
diskpart(WINKEY + R then
select vdisk file="<PathToVHDX>"
Expand the .vhdx file to at least 500GB:
expand vdisk maximum=500000(500GB)
Verify it has expanded:
Now we must expand it in Arch Linux.
Open Arch Linux
Find the root disk (
sudo resize2fs /dev/sdX(X being your root)
Verify it has resized under the Size column:
We need to create a wsl.conf due to:
- poor disk and network performance of NTFS <-> ext4 directories
- conflicting binaries with Windows PATH being appended to the Linux PATH
- poor disk and network performance of Windows binaries in WSL
- poor network performance of the internal DNS server
- and AOSP, Chromium, and Linux require strict case-sensitive filesystems.
Open Arch Linux
Create and edit the VM’s wsl.conf:
sudo vim /etc/wsl.conf
[automount] options = "case=dir" [interop] appendWindowsPath = false [user] default = <username> [network] generateResolvConf = false
sudo vim /etc/resolv.conf
Remove everything and enter
nameserver <DNS server of your choice>
Because we don’t have proper systemd (for resolved and resolvconf), the file gets cleared and never saves. Lock it from all modifications to save it permanently:
sudo chattr +i /etc/resolv.conf
Exit and shutdown WSL:
Create a system
.wslconfigin your Windows user directory:
[wsl2] swap = 70G localhostForwarding = true nestedVirtualization = true guiApplications = true
AOSP requires a lot of memory so create a swapfile just in case. Production builds of GrapheneOS are extremely memory intensive. Can be any size you want. Then save.
- Start up WSL and make sure you have a
AOSP emulator pre-configuration and nested virtualisation:
Emulator can make use of nested virtualisation (KVM). Permissions are weird on WSL though and due to lack of proper systemd, require some workarounds.
Open Arch Linux
Add yourself to the
ulimit -n 1048575as the soft limit is hardcoded
1024and can’t be changed even though emulator requires more than 1024 file descriptors or it will crash and freak out. It also doesn’t seem to know how to ask for the hard limit of file descriptors.
/etc/security/limits.confdoesn’t seem to work on WSL and systemd ignores
DO NOT raise 1048575 ANY HIGHER. There is a bug with pam_limits where if the file descriptors limit is greater than or equal to
sysctl fs.nr_open, it will break sudo. The default seems to be 1048576, so set it one below that.
/etc/sysctl.conf is ignored on WSL so no reason to attempt to modify it.
If you do happen to lock yourself out from this, open a new window and run
wsl -d archlinux --user root and make the proper change. Don’t ask how I know.
It’s possible KVM may not work still because it can’t access
/dev/kvm despite being added to the
kvm group, also due to weird WSL things. I just do
sudo chmod 777 /dev/kvm. It doesn’t matter if it’s 777 because all files are created with a 000 umask on NTFS drives anyways since metadata isn’t included by default and is still experimental. WSL is not for security.
If you want to automatically set
/dev/kvm to 777, you can set it as a WSL2 startup command in
[boot] command = chmod 777 /dev/kvm
From this point on, you will ALWAYS need to do stuff in the actual Linux ext4 root.
/home is apart of
/ so you should just do your stuff in
~/. DO NOT do stuff in NTFS drives (
/mnt/c for example) as I mentioned above it’s extremely slow. This is the closest to a real Linux setup.
You can now follow https://grapheneos.org/build like you would on normal Linux exactly as-is. Building emulator yields near-bare-metal times (2 hours 46 minutes on WSL Arch Linux, 2 hours 6 minutes on bare-metal Arch Linux).
AOSP emulator segmentation fault and poor performance
You (might) need to disable the GPU (yeah, weird) to get high performance 60 FPS in the Android Virtual Device’s config.
- Assuming you built emulator successfully at this point navigate to the output, example:
Then start emulator again. You should have high performance, extremely fluid, 60 FPS. It might also fix a possible segfault.
It’s possible this isn’t necessary and I suggest just trying to run emulator as-is before deciding if you need it. On my old machine (i7-8700k + NVIDIA GTX 1070) this was mandatory, but on my new machine (Ryzen 9 3900XT, NVIDIA RTX 3080) this was not needed.
Thanks and credit to author of this article:
commit a8d58587976f9c479f30cb4a69b032af412de70f Author: June <june@******.**> Date: Sunday, May 1, 2022
Author of this paper is my friend, June. I do not take any credit for this. I am simply hosting it as June is no longer on GitHub. Several people have asked me for this guide since the original repo does not exist anymore.