Anatomy of Android X86 Installation

Android x86 ISO (http://www.android-x86.org/ ) is under 200MB. Hence, it is an attractive small distribution to explore. The ISO is a livecd with an option to install. However, it is fun to use this as a platform to explore and learn what else can we do with it, without rebuilding from the source.

Booting starts with a boot loader like grub or syslinux. Two parameters are mandatory – the linux kernel and an initial RAM file system (initrd.img). There may be additional kernel options which are used as and when needed by examining /proc/cmdline. The kernel passes control to an executable called init in initrd. The init executable is often, though not necessarily, a shell script. This script will create a usable system – find critical devices and mount the real root file system. It will finally switch root to the real root and start another init script/executable. In case the executable is not called init, it may be passed as a parameter to an option called init.

We will explore the initrd.img on the android x86 ISO and see how it works and what we may do with it. Extract the contents of the initrd.img in a working directory.

$sudo mount /repos/android-x86-4.2-20130228.iso /mnt/livecd/
$ cp /mnt/livecd/initrd.img initrd.gz
$ zcat initrd.gz | cpio -ivd

Init script is about 200 lines and easily readable. We can get an insight into what to look for by looking at the contents of isolinux.cfg in /mnt/livecd/isolinux:

label livem
menu label Live CD - ^Run Android-x86 without installation
kernel /kernel
append initrd=/initrd.img root=/dev/ram0 androidboot.hardware=android_x86 video=-16 quiet SRC= DATA=

Two unusual parameters are SRC and DATA. The init script searches for a root device by mounting each available disk partition and dvd and searching for ramdisk.img and system.sfs in $SRC. So, we may copy the contents of /mnt/livecd into /android in the disk partition containing /boot. We add the following entry in grub.cfg - preferably by editing 40_custom in grub.d and regenerating grub.cfg.

menuentry 'Android '{
linux /android/kernel root=/dev/ram0 androidboot.hardware=android_x86 video=-16 quiet SRC=/android DATA=
initrd /android/initrd.img
}

If our understanding is correct, we should be able to boot into Android from the local disk using grub. In my experiments, android booted on a netbook but not on a desktop. It is easy to understand the reason. There are no drivers in initrd. The kernel is supposed to include the needed drivers for accessing the core devices. In fact, the init script has the option to boot from an NFS disk provided the kernel is customised to include the required Ethernet and nfs drivers. The pre-built kernel is intended for use with common netbooks and small screen x86 devices.

Creating a directory /android/data allows persistent storage. Alternatively, DATA can be assigned a block device.

Booting over the Network

The next experiment would be that can we boot over the network without customising the kernel? Can we can follow the example of Puppy Linux and copy the needed files inside the initrd.img?

The init script mounts a disk partition on /mnt and searches for the needed files. We can modify the script so that if it finds the files under /mnt, it will not mount a partition.

On the dhcp, pxe boot server:

  1. Create a directory android in html-root: /var/www/html (Fedora) or /var/www (Ubuntu). We use http rather than tftp as that is faster.

  2. Copy contents of /mnt/livecd in it.

  3. Enabling pxe boot

    1. Copy pxelinux.0 from syslinux

    2. Create a directory pxelinux.cfg

    3. Move isolinux/isolinux.cfg as pxelinux.cfg/default

    4. Move android-x86.png and vesamenu.cfg from isolinux into android,i.e. one level up.

  4. Creating a new initrd

    1. Extract contents of intrd.img into a working directory

    2. Move install.img, ramdisk.img and system.sfs in mnt folder of the working dirctory.

    3. Modify init script to ignore mounting if /mnt/ramdisk.img exists. E.g. a quick fix is to call try_mount conditionally in check_root:
      if [ ! -f /mnt/ramdisk.img ]; then
      try_mount ro $1 /mnt && [ -e /mnt/$SRC/ramdisk.img ]
      [ $? -ne 0 ] && return 1
      fi

    4. Create a new initrd.img and replace the one in /var/www/android

  5. Configure dhcp with the following line to boot pxelinux using http:

    filename "http://server/android/pxelinux.0";

In my experiments, this worked on both the netbook and the desktop. However, the design of Android is around a small device. So, using it on a desktop is an interesting experiment but certainly not worth frequent use.

The first lesson is that creating a customised initrd is not very difficult.

The more important lesson, though, is that it makes it very noticeable that the ease of use and the ability to just access an incredible amount of information comes at a price - the price of security and privacy. The risk of owning such devices may be far too high if one is in the habit of leaving the device unattended!

May 2013

Comments