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):

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:

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).

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 GitHub - Genymobile/scrcpy: Display and control your Android device instead.

To build scrcpy (scrcpy/doc/linux.md at master ยท Genymobile/scrcpy):

You can then access your Android display by simply using scrcpy.

Screenshot_2024-08-22_17-05-44.png

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: