Run Android using QEMU
History
Android Emulator (goldfish/ranchu)
Google has been providing android emulator for application development through Android Studio. It’s possible to create virtual devices with various characteristics, and images are available for every Android major/minor versions.
This emulator is based on a downstream fork of QEMU (last merge was QEMU 2.12 + various patches applied):
https://android.googlesource.com/platform/external/qemu/ (see branches
emu-*-release
for latest versions)
It provides specific devices, new command line switches and a UI based on Qt. goldfish
was the first name of this platform, and it was later superseded by ranchu
(https://groups.google.com/g/android-emulator-dev/c/dltBnUW_HzU).
Despite being called an emulator, it provides also virtualization acceleration (through kvm on Linux, whpx/haxm on Windows and hvf on MacOS), and it seems to be the main use case these days.
Note: I have not been able to launch any aarch64 vm from a Linux/Windows x64 host. It seems like command line generated is incorrect for any Android image (>= 7.0). So virtualization seems to be the only solution working nowadays.
Cuttlefish
In 2018 (AOSP 9.0), Google started to work on a new solution for Android virtualization, named Cuttlefish.
https://source.android.com/docs/devices/cuttlefish
The idea is to provide a virtualization oriented solution, with less maintenance:
use upstream Kernel/QEMU
use virtio devices
leverage kvm for acceleration (thus, it’s only available on Linux)
adapted for cloud environment
Initially, QEMU was used. It was later replaced by CrosVM. However, it’s still possible to use QEMU, with or without kvm acceleration.
Those two presentations can help to understand the philosophy or Cuttlefish:
LPC 2018: https://lpc.events/event/2/contributions/269/attachments/56/63/Kernel_Hacking_with_Cuttlefish.pdf
Conclusion
Today, we have two solutions for running Android VM.
The first, named Android emulator, goldfish, or ranchu, is integrated in Android Studio, and targets applications developers. It uses a downstream fork of QEMU.
The second, named Cuttlefish, targets AOSP developers, working on the system itself. It uses upstream QEMU/Kernel.
Run Android using Cuttlefish
Now we saw the different existing solutions, we’ll focus on Cuttlefish. It’s supported on any Debian/Ubuntu distribution. https://source.android.com/docs/devices/cuttlefish/get-started
1. Install cuttlefish tools
First, you need to install cuttlefish packages on your machine, and reboot.
sudo apt install -y git devscripts equivs config-package-dev debhelper-compat golang curl
git clone https://github.com/google/android-cuttlefish
cd android-cuttlefish
tools/buildutils/build_packages.sh
sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
sudo dpkg -i ./cuttlefish-user_*_*64.deb || sudo apt-get install -f
sudo usermod -aG kvm,cvdnetwork,render $USER
sudo reboot
2. Download Android image and cvd-host package
Images can be compiled from source (https://source.android.com/docs/setup/build/building), or simply downloaded from https://ci.android.com (aosp-main
branch for x64, aosp-main-throttled
for aarch64).
x64 images: https://ci.android.com/builds/branches/aosp-main/grid?legacy=1, and select
aosp_cf_x86_64_phone-trunk_staging-userdebug
aarch64 images: https://ci.android.com/builds/branches/aosp-main-throttled/grid?legacy=1 , and select
aosp_cf_arm64_only_phone-trunk_staging-userdebug
Select artifacts, then download aosp_cf_*img*.zip
and cvd-host_package.tar.gz
3. Decompress cvd tools and image in the same directory
mkdir android-image
pushd android-image
unzip ../aosp_cf_*.zip
tar xzvf ../cvd-host_package.tar.gz
4. Run Cuttlefish
By default, vm will be ran using crosvm. Option -vm_manager
allows to use qemu instead.
HOME=$(pwd) ./bin/launch_cvd -vm_manager qemu_cli -report_anonymous_usage_stats=n --start_webrtc=false
5. Access system
Cuttlefish redirects various logs, including kernel (cuttlefish/instances/cvd-1/kernel.log
).
VM will be booted once this message appears (either in your terminal, or in kernel log).
The easiest way to access VM, is to use adb. adb shell
will provide a shell running on the system.
For graphical access, cvd offers a web page. However, it seems to work only with crosvm, and not when using QEMU. The easiest way is to use https://github.com/Genymobile/scrcpy instead.
To build scrcpy (https://github.com/Genymobile/scrcpy/blob/master/doc/linux.md):
You can then access your Android display by simply using scrcpy
.
Run Android using Cuttlefish and a custom build of QEMU
Cuttlefish comes with a prebuilt upstream QEMU (very recent, tracking master), located in bin/x86_64-linux-gnu/qemu/
, and coming from cvd package.
launch_cvd
allows you to specify a custom path where to find qemu-system-*
binaries using -qemu_binary_dir=
option. You can then point directory to your QEMU build folder, or to a directory containing a wrapper script, if you want to edit QEMU options, or wrap it with a tool, like perf
.
Note: launch_cvd
parses stdout from QEMU. Thus, if you have a wrapping script, you need to write output to stderr instead.
Note: launch_cvd
requires to set your HOME folder to current directory. Thus, you should be aware of this in case you write a wrapper script using this.
This is an example with a custom wrapper to print QEMU full command line: