Giving your Android Emulator a Boost: Building Android ICS with Goldfish & x86 KVM support on EC2 - TestObject

Posted by | April 17, 2012 | Company | 3 Comments

Objective

This article takes the developer through the Android ICS build for the x86 architecture. In conjunction with Intels Linux 2.6 Kernel supporting hardware-assisted virtualization (hypervisor) the Android AVD x86-emulator easily outperforms native ARM hardware performance.

Try fast emulators in your browser. Sign up for FREE


If you have any feedback or questions, feel free to leave a comment or drop me a mail: erik.nijkamp@testobject.org

0. Quickstart

For those who don’t want to get their hands dirty (this takes several hours), we’ve compiled, bundled and pre-configured a system image for your convenience. Simply follow the 5 steps below and your Android ICS emulator-x86 AVD should be up and running.

1. Download the Precompiled System Image

First, download the system-image bundle which can be obtained from our site:
$ wget http://download.testobject.org/dev/android_ics_x86_goldfish.tar.gz

2. Untar the System Image

Next, extract the tar.gz file into your Android SDK folder:
$ tar -zxvf android_ics_x86_goldfish.tar.gz -C ~/<sdk_dir>

3. Enable KVM Support

Additionally, we have to enable hardware-assisted virtualization to get the most out of Intels Linux kernel. See Intels guide [6] for a more detailed explanation.
$ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
Next, we have to ensure that our current user is added to the groups kvm and libvirtd.
$ sudo adduser <your_user_name> kvm
$ sudo adduser <your_user_name> libvirtd
Finally, verify that KVM support is enabled with the following command.
$ sudo virsh -c qemu:///system list
Your screen will paint the following below if successful:
Id Name State
———————————-

4. Create a x86 AVD

Now open the AVD manager and create a new AVD based on the x86 system-image.
$ ~/<sdk_dir>/tools/android
First, check that you’ve installed the Android 4.0.3 (API 15) SDK Platform and that the newly added system-image shows up as “Intel x86 Atom System Image”.


Next, to create a new AVD we perform the following steps:
  1. Click on “Tools”, “Manage AVDs” and “New..”
  2. Name the AVD “x86_4_0_3″
  3. Select “Android 4.0.3 – API Level 15″ as Target
  4. Choose “Intel Atom (x86)” as CPU/ABI
  5. Click “Create AVD”

5. Run the x86 Image from CLI

Finally, we fire up the x86 emulator with enabled KVM acceleration.
$ ~/<sdk_dir>/tools/emulator-x86 -avd x86_4_0_3 \
-kernel ~/<sdk_dir>/system-images/android-15/x86/kernel-qemu \
-qemu -m 1024 -enable-kvm
Hurray!

1. Build from sources

In the following we discuss building both Intels Kernel on Amazons EC2 and the Android ICS platform with ASOP sources.

Creating an EC2 Instance

The official build procedure [1] recommends to rely on Ubuntu 10.04 (LTS) 64-bit with 16 GB of RAM and 25 GB of free disk-space for a single build. Similar to [2], we observed that the entire build process requires about only 4 GB of ram, but the CPU is easily maxed out. Accordingly we diverge from the recommended configuration and opt for maximum performance.

1. Create Instance

First, we create a new EC2 instance which does the heavy lifting for us. At the time of this writing the instance type ‘c1.xlarge’ (or ‘High-CPU Extra Large Instance’) comes with 8 cores (20 ECUs) with roughly 52 gflop/s [3] and 7 GB of ram.
  1. Log into your AWS console
  2. Create a new instance and select “More Amazon Machine Images” (Quick Launch Wizard)
  3. Select a Ubuntu 10.04 (LTS) 64-Bit instance e.g. ami-10794c64
  4. Edit details and change the type to “c1.xlarge”
  5. Launch

2. Increase EBS storage

Next, we have to increase the EBS storage of the created instance. Instances typically come with 7 or 16 GB EBS pre-allocated volumes, but a full ICS build requires up to 50 GB. Alternatively, as in [2], the ephemeral disks can be used in a RAID0 setup with no allocation costs.
  1. Stop the instance
  2. Navigate to “Elastic Block Store” and “Volumes”
  3. Create a snapshot of the volume associated with your instance
  4. Navigate to “Snapshots” and wait for completion
  5. Create a 50GB volume from the snapshot (ensure that the correct availability zone is set)
  6. Detach the volume associated with the instance
  7. Attach the 50GB volume to the instance using device ‘/dev/sda1′
  8. Delete the snapshot and detached volume

3. Increase Partition

Next we launch the instance and increase the size of the filesystem.
$ ssh -i ~/.ssh/*.pem ubuntu@*.*.compute.amazonaws.com
$ sudo resize2fs -p /dev/sda1

4. Increase Swap

The official build documentation recommends a combined total of 16GB of RAM + Swap. We have 7GB of RAM on this instance, but since we have observed that at most 4GB of RAM are allocated during this procedure, we reduce the available Swap space to 8GB.
$ sudo dd if=/dev/zero of=/tmp/swapfile bs=1M count=8192
$ sudo mkswap /tmp/swapfile
$ sudo swapon /tmp/swapfile

Preparing the Build Environment

In the following we are going to install the required packages. As mentioned previously, Ubuntu 10.04 64-bit is recommended. Next, establish a ssh terminal connection to the launched EC2 install and perform the subsequent steps.

1. Java

The Sun JDK is no longer in Ubuntu’s main package repository. In order to download it, you need to add the appropriate repository and indicate to the system which JDK should be used.
$ sudo add-apt-repository ppa:sun-java-community-team/sun-java6
$ sudo apt-get update
$ sudo apt-get install sun-java6-jdk

2. Build Tools

Additionally a set of build tools and required dependencies is installed.
$ sudo apt-get install git-core gnupg flex bison gperf build-essential \
zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \
x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \
libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \
libxml2-utils xsltproc

Building the Kernel Provided by Intel

Next, we are going to compile Intels modified Linux 2.6 kernel which comes with native x86 KVM hardware acceleration support. The following steps are borrowed from Intels guide [4].

1. Download Kernel Sources

Change to the directory holding the Android sources:
$ cd ~/android
Intel Android developer site provided a Linux 2. kernel SDK for x86 which included many drivers that Intel developed. Go to Intel Android Developer site to download Android* 2.3.7 (Gingerbread) x86 Emulator Image Add-on.
$ wget http://software.intel.com/sites/landingpage/android/Intel_x86_sysimg_2.3.7_Source_Files.zip
$ unzip Intel_x86_sysimg_2.3.7_Source_Files.zip
$ tar -xvf kernel_sdk_x86.tar.gz
We switch to the directory that holds your kernel files.
$ cd kernel

2. Configure the Kernel

We choose the goldfish target platform, which is a patched Linux kernel with additional hardware support for the QEMU-based Android emulator.
$ cp ~/android/kernel/arch/x86/configs/goldfish_defconfig .config

3. Build the Kernel

Next we trigger the build.
$ make ARCH=x86 –j12

4. Copy the Kernel Images

$ cp ~/android/kernel/arch/x86/boot/bzImage ~/android/platform/prebuilt/android-x86/kernel/kernel-qemu
$ cp ~/android/kernel/vmlinux ~/android/platform/prebuilt/android-x86/kernel/vmlinux-qemu

Building the Android ICS Platform

Next, we are going to compile the Android ASOP 4.x sources for the x86 target platform. The following steps are borrowed from the guides [1,2].

1. Screen Session

As the build can take several hours and the ssh connection might be lost in the meanwhile, we use a tool ‘screen’ which allows us to re-connect to a user-session.
$ screen -S build

2. Installing Repo

Repo is a tool that makes it easier to work with Git in the context of Android. To install, initialize, and make Repo executable, follow these steps:
$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ sudo sysctl -w net.ipv4.tcp_window_scaling=0
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

3. Get the Source

After installing Repo, set up your client to access the android source repository:
$ mkdir -p ~/android/platform
$ cd ~/android/platform
$ repo init -u https://android.googlesource.com/platform/manifest
To pull down files to your working directory from the repositories as specified in the default manifest, run
$ repo sync -j4

4. Verifying Git Tags

Load the following public key into your GnuPG key database. The key is used to sign annotated tags that represent releases.
$ gpg –import
Copy and paste the key(s) below, then enter EOF (Ctrl-D) to end the input and process the keys.
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV
lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7
8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD
u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z
wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq
/HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5
jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4
MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9
b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv
aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k
cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX
gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI
2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl
QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up
hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk
C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX
LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+
OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M
pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s
KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb
N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA
vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo
G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ
hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l
EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=
=Wi5D
-----END PGP PUBLIC KEY BLOCK-----
Press Enter and key in Ctrl+D (End of File) to finish.

5. Initialize the Build Environment

Initialize the environment with the envsetup.sh script. Note that replacing “source” with a single dot saves a few characters, and the short form is more commonly used in documentation.
$ source build/envsetup.sh

6. Choose a Build Target

Choose which target to build with lunch. Our target architecture is x86, thus we pass the configuration “full_x86-eng” as an argument:
$ lunch full_x86-eng
This will output some information about the build, similar to that below:

7. Build the Code

Build everything with make. GNU make can handle parallel tasks with a -jN argument, and it’s common to use a number of tasks N that’s between 1 and 2 times the number of hardware threads on the computer being used for the build. There are 8 cores (20 ECUs) on a c1.xlarge, so we used numbers between 12 and 16 for CPU limited tasks. We opted to use a ‘j’ value of 12 which seemed to work reasonably.
$ make -j12

2. Configure AVD emulator

Finally, we create an emulator AVD configuration which points to the x86 Android ICS build and the Intel Linux kernel. Therefore the following steps have to be performed on your local machine. The following steps are borrowed from Intels guide [5].

1. Enable KVM Support

Following Intels guide [6] your first have to ensure that KVM support is enabled for your local system.
$ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
Next we have to ensure that our current user is added to the groups kvm and libvirtd.
$ sudo adduser your_user_name kvm
$ sudo adduser your_user_name libvirtd
Finally verify that KVM support is enabled with the following command.
$ sudo virsh -c qemu:///system list
Your screen will paint the following below if successful:
Id Name State
———————————-

2. Download Images

We download the compiled kernel and platform images files to our local system.
$ mkdir ~/<sdk_dir>/system-images/android-15/x86
$ cd ~/<sdk_dir>/system-images/android-15/x86
$ scp -i ~/.ssh/*.pem ubuntu@*.compute.amazonaws.com:/home/ubuntu/android/kernel/arch/x86/boot/bzImage kernel-qemu
$ scp -i ~/.ssh/*.pem ubuntu@*.compute.amazonaws.com:/home/ubuntu/android/platform/out/target/product/generic_x86/userdata.img .
$ scp -i ~/.ssh/*.pem ubuntu@*.compute.amazonaws.com:/home/ubuntu/android/platform/out/target/product/generic_x86/ramdisk.img .
$ scp -i ~/.ssh/*.pem ubuntu@*.compute.amazonaws.com:/home/ubuntu/android/platform/out/target/product/generic_x86/system.img

3. Create a x86 configuration file

We copy the original ARM-specific configuration file and modify it slightly to match the x86 architecture.
$ cd ~/<sdk_dir>/system-images/android-15/armeabi-v7a
$ cp source.properties ../x86 $ vi ../x86/sources.properties
In sources.properties replace “SystemImage.Abi=armeabi-v7a” by “SystemImage.Abi=x86″ to point to the “x86″ folder and indicate that this system-image is compiled for the x86 architecture.

4. Create an x86 AVD Image

Now we fire up the AVD manager and create a new AVD based on the x86 system-image.
$ ~/<sdk_dir>/tools/android
First, check that the newly added system-image shows up as “Intel x86 Atom System Image”.


Next, to create a new AVD we perform the following steps:
  1. Click on “Tools”, “Manage AVDs” and “New..”
  2. Name the AVD “x86_4_0_3″
  3. Select “Android 4.0.3 – API Level 15″ as Target
  4. Choose “Intel Atom (x86)” as CPU/ABI
  5. Click “Create AVD”

5. Run the AVD Image

$ ~/<sdk_dir>/tools/emulator-x86 -avd x86_4_0_3 \
-kernel ~/<sdk_dir>/system-images/android-15/x86/kernel-qemu \
-qemu -m 1024 -enable-kvm
Which finally runs the Android ICS image with Intels x86 emulator and hardware-assisted virtualization.
Hurray! If you have any feedback or questions, feel free to leave a comment or drop me a mail: erik.nijkamp@testobject.org


3 Comments

  • Joy says:
    Wow, I thought this was going to just be a quick tutorial on getting the Intel HAXM up and running. Didn’t expect such a concise tutorial on using EC2 and compiling my own AVD. Thanks for the post.
  • john says:
    I can’t get this to work.. my sdk-dir is android and there is no tools directory
    • Erik Nijkamp says:
      John, thanks for the reply! The android sdk directory contains folders such as tools, add-ons, platform, system-images. Your sdk installation must be broken if these are missing. Anyhow, nowadays you can just navigate to the sdk manager (tools/android), then download the “Intel x86 Atom System Image” and install the “Intel x86 Ermulator Accelerator (HAXM)” and this should give you hardware-accelerated emulators out of the box. Let me know if you have further issues ;)

Leave a Reply

Your email address will not be published.

Current month ye@r day *

Simplify your app testing today.
GET STARTED
Have a question? Give our sales team a call. +49 (0) 3302 2097320