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.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-utilsNext, we have to ensure that our current user is added to the groups kvm and libvirtd.
$ sudo adduser <your_user_name> kvmFinally, verify that KVM support is enabled with the following command.
$ sudo adduser <your_user_name> libvirtd
$ sudo virsh -c qemu:///system listYour 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/androidFirst, 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:
- Click on "Tools", "Manage AVDs" and "New.."
- Name the AVD "x86_4_0_3"
- Select "Android 4.0.3 - API Level 15" as Target
- Choose "Intel Atom (x86)" as CPU/ABI
- 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 \Hurray!
-kernel ~/<sdk_dir>/system-images/android-15/x86/kernel-qemu \
-qemu -m 1024 -enable-kvm
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.- Log into your AWS console
- Create a new instance and select "More Amazon Machine Images" (Quick Launch Wizard)
- Select a Ubuntu 10.04 (LTS) 64-Bit instance e.g. ami-10794c64
- Edit details and change the type to "c1.xlarge"
- 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.- Stop the instance
- Navigate to "Elastic Block Store" and "Volumes"
- Create a snapshot of the volume associated with your instance
- Navigate to "Snapshots" and wait for completion
- Create a 50GB volume from the snapshot (ensure that the correct availability zone is set)
- Detach the volume associated with the instance
- Attach the 50GB volume to the instance using device '/dev/sda1'
- 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 ~/androidIntel 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.zipWe switch to the directory that holds your kernel files.
$ unzip Intel_x86_sysimg_2.3.7_Source_Files.zip
$ tar -xvf kernel_sdk_x86.tar.gz
$ 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/platformTo pull down files to your working directory from the repositories as specified in the default manifest, run
$ cd ~/android/platform
$ repo init -u https://android.googlesource.com/platform/manifest
$ 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 --importCopy 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-engThis 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-utilsNext we have to ensure that our current user is added to the groups kvm and libvirtd.
$ sudo adduser your_user_name kvmFinally verify that KVM support is enabled with the following command.
$ sudo adduser your_user_name libvirtd
$ sudo virsh -c qemu:///system listYour 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-v7aIn 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.
$ cp source.properties ../x86 $ vi ../x86/sources.properties
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/androidFirst, 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:
- Click on "Tools", "Manage AVDs" and "New.."
- Name the AVD "x86_4_0_3"
- Select "Android 4.0.3 - API Level 15" as Target
- Choose "Intel Atom (x86)" as CPU/ABI
- Click "Create AVD"
5. Run the AVD Image
$ ~/<sdk_dir>/tools/emulator-x86 -avd x86_4_0_3 \Which finally runs the Android ICS image with Intels x86 emulator and hardware-assisted virtualization.
-kernel ~/<sdk_dir>/system-images/android-15/x86/kernel-qemu \
-qemu -m 1024 -enable-kvm
Hurray! If you have any feedback or questions, feel free to leave a comment or drop me a mail: erik.nijkamp@testobject.org
[1] http://source.android.com/source/initializing.html
[2] http://www.thatsgeeky.com/2011/12/building-ice-cream-sandwich-android-v4-for-virtualbox-on-ec2
[3] http://www.st.ewi.tudelft.nl/~iosup/ec2perf-sci-comp09cloudcomp.pdf
[4] http://software.intel.com/en-us/blogs/2012/03/06/hands-on-notesbuild-android-x86-ics-4-virtualbox-from-google-virtualbox-target-and-intel-kernel
[5] http://software.intel.com/en-us/articles/android-ia-emulator-gingerbread/
[6] http://software.intel.com/en-us/blogs/2012/03/12/how-to-start-intel-hardware-assisted-virtualization-hypervisor-on-linux-to-speed-up-intel-android-x86-gingerbread-emulator/
[2] http://www.thatsgeeky.com/2011/12/building-ice-cream-sandwich-android-v4-for-virtualbox-on-ec2
[3] http://www.st.ewi.tudelft.nl/~iosup/ec2perf-sci-comp09cloudcomp.pdf
[4] http://software.intel.com/en-us/blogs/2012/03/06/hands-on-notesbuild-android-x86-ics-4-virtualbox-from-google-virtualbox-target-and-intel-kernel
[5] http://software.intel.com/en-us/articles/android-ia-emulator-gingerbread/
[6] http://software.intel.com/en-us/blogs/2012/03/12/how-to-start-intel-hardware-assisted-virtualization-hypervisor-on-linux-to-speed-up-intel-android-x86-gingerbread-emulator/


thanks a ton for this. I appreciate you taking your time to lay out the steps on how to reproduce these emulator images.
ReplyDeletejust tested this with your precompiled files and it works flawlessly here.
i now have both x86 emulation + GPU acceleration thanks to you guys.
Could we get this ICS x86 Emulator ported to Mac OS X as well? I am loving the Gingerbread version.
ReplyDeleteHi Luis de la Rosa,
DeleteTy Smith mentioned that the intel HAX driver seems to work with OSX.
http://tysmith.me/post/21442015873/icsx86gpu
The emulator is running very well on my Ubuntu 12.04 x86_64 machine, but the window is limited to the Android screen, I don't see the emulator controls (keyboard, h/w buttons). Is there a switch to have this work? Thanks!
ReplyDeleteI found that fiddling around woth the emulator optins eventually gave me the controls back. I changed values for 'Hardware Back/Home keys' and 'Keyboard lid support' back and forth and now the emulator controls are showing again. Hope this helps.
DeleteHow can I make the window bigger than regular Android screen? That's not really convenient.
ReplyDeleteDoes it work in windows ? It will be a great help if you please assist me in installing it in Windows System.
ReplyDeleteI followed the 0. Quickstart. At the end I met this error:
ReplyDelete> emulator: ERROR: unknown virtual device name: 'x86_4_0_3'
What is the reason? How can I fix this.