Sunday, February 12, 2012

Android on your EEEPC

Hello everyone,

So, this article is about running Android on your x86 computer, here we'll use the eee-pc since that is supported in a very nice way by the people behind the android-x86 project.

What you will get:
  • Ice Cream Sandwich
  • A Live-USB stick that you can boot android from without touching your installed software/os at all. Or you can choose to install it to hard-drive, enabling you to keep changes you make over reboots.
  • Camera is working
  • WLAN is working
  • Google Apps are installed (Market, Talk, GMail etc)

What's not working
  • Youtube
  • Face unlock
  • Many android-apps that expect ARM architecture

So, you could just download the iso from http://www.android-x86.org . But then you would get an image where you can't use the browser and you can't read e-mail. Also, you would miss out on the fun on rolling your own bleeding edge android rom :)

First, this article is standing on the shoulders of giants, most of the information has been taken and tweaked from these web-pages. But as usual, the devil is in the details.

Links

Get the install dependencies (for 64bit ubuntu 11.10)
Get the packages from the Ubuntu repository
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 lib32readline-gplv2-dev lib32z-dev libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils xsltproc openjdk-6-jdk

sudo apt-get install libx11-dev:i386
Get Repo
mkdir ~/bin
export PATH=~/bin:$PATH
curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
chmod a+x ~/bin/repo

Get the android-x86 source code
A warning, on the android-x86 page, they tell you to use the sourceforge mirror, I had problems with that one. I didn't get all dependencies downloaded. I got a repo-warning about libcamera and I got lots of build-errors about LOCAL_SDK_VERSION being set to bad values. This turned out to be because I had no prebuilt directory. After I re-downloaded everything and used the android-x86 git-repository, I got everything and compilation was smooth as butter :) (Well, almost, it didn't like OpenJDK, but that was a simple fix).

mkdir -p ~/devel/android-x86
cd ~/devel/android-x86
repo init -u http://git.android-x86.org/manifest -b $branch
# This will download about 11GB worth of data!
repo sync
Then, enable building with OpenJDK
I did this by going in to build/core/ and creating a new git-branch. The reason for this is that it makes it easier when there is an update available from upstream, you can just do repo sync and then rebase your branch to be on top of it.
cd build/core
git checkout -b fix_jdk
And then apply this patch which is inlined here:
diff --git a/core/main.mk b/core/main.mk
index 569d4dc..2912c70 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -114,9 +114,9 @@ endif
# Check for the correct version of java
java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')
-ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
-java_version :=
-endif
+#ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
+#java_version :=
+#endif
ifeq ($(strip $(java_version)),)
$(info ************************************************************)
$(info You are attempting to build with the incorrect version)
You can apply it by:

cd ~/devel/android-x86/build
# this should of course be the path to where you have stored the patch
patch -p0 < openjdk.patch

Then source build environment and start build
This will take a while, I think it took about 1 hour for me (quad-core amd 3ghz, 8gb ram and ssd disk).
cd ~/devel/android-x86
source build/envsetup.sh
# you could probably also build a user-build with: lunch eeepc-user
lunch eeepc-eng
# m is shorthand for make, the macro is in envsetup.sh
# This also makes sure that you can be in any directory and still get a proper build
m -j4 iso_img

While you wait, download gapps (at the time of writing gapps-ics-20120207-signed.zip)

Unpack to ~/devel/android-gapps
mkdir -p ~/devel/android-gapps
mv ~/Downloads/gapps* ~/devel/android-gapps
cd ~/devel/android-gapps
unzip gapps*
Create directory for patching generated iso-image

mkdir ~/devel/android-hacking
Wait for build to complete. Now comes the tricky part. First, the build will create an iso-image that doesn't have google apps. Also, this image does not have room in it to add the google apps package. So we will unpack the iso-image, resize the system filesystem, add gapps package and then sew everything back up afterwards.
cp ~/devel/android-x86/out/target/product/eeepc/eeepc.iso ~/devel/android-hacking
cd ~/devel/android-hacking

mkdir android-image
mkdir tmp

# extract image to android-image directory
bsdtar -C android-image -xf eeepc.iso
cd android-image
# if your system image is squashed (I didn't do this. It can be configured, then run)
unsquashfs system.sfs
# resize system.img so we can fit gapps, could probably be enough with 100 mb instead of 256.

dd if=/dev/zero bs=1M count=256 >> system.img
resize2fs system.img
$ cd ..
# if squashed
$ sudo mount -o loop android-image/squashfs-root/system.img tmp
# else
$ sudo mount -o loop android-image/system.img tmp
Now we have extracted the iso, resized the system partition and loopback mounted it to the tmp directory (meaning, we can use it as a normal file-system).

Install gapps into android system.
Now we will install the gapps. The gapps package I used is for arm-devices. Therefore we can only use the apps that only have a java/dalvik component. The ones that use ndk and arm-specific libraries can't be used.

sudo cp ../android-gapps/system/app/* tmp/app
sudo cp ../android-gapps/system/etc/permissions/* tmp/etc/permissions/
sudo cp ../android-gapps/system/framework/* tmp/framework/
There, now we have everything where we want it. Time to wrap it up.
Begin by unmounting the tmp directory so we get the system.img back as it should be
sudo umount tmp
# if squashed
mksquashfs android-image/squashfs-root/system.img system.sfs

Create iso-image
genisoimage -vJURT -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -input-charset utf-8 -V "Android-x86 LiveCD" -o eeepc-gapps.iso android-image/

Make it bootable from USB
isohybrid eeepc-gapps.iso

Write it to USB
Now everything is done. you have a file eeepc-gapps.iso that you can burn to a cd or install on a usb-stick. I very much prefer USB. This is how you get it to a usb-stick. First you need to be sure where your USB-stick is. If you get this wrong, you will Kill one of your harddrives. You don't want that. If you are unfamiliar with using the terminal, please use unetbootin or some other tool to write the image to a usb-stick.
sudo dd if=eeepc-gapps.iso of=/dev/sdc


There, you did it!
Now you can put your USB stick in an eee-pc and boot it. I had to go into the BIOS and change the boot-order since my USB-stick showed up as a hard-disk.

But after that, whenever you boot with this usb-stick plugged in, you will get android Ice Cream Sandwich instead of your other operating systems! :)

Some things are left to do though
  • This won't store settings over rebooots.
  • It won't handle suspends very well
  • Since I don't have a x86 gapps package, not all features work (Face unlock, youtube)
Maybe I'll write another article when I've fixed that :)

Cheers,
Daniel