====== Embedded Gentoo for Android ======
---- dataentry project ----
Name_ : Embedded Gentoo for Android
Tags_tags : android, gentoo
Description_ : A method of installing Gentoo on Android (within a CHROOT)
Last Update_dt : 2011-04-27
----
Well, me being a gentoo fanatic and all, I decided it was time to see if I could get a copy of it running on my good ol' moto.
This is going to be kind of a pet project for awhile, as I'm almost positive it may be beyond my capabilities. However, who knows?
===== Step 0: Prerequisites =====
I assume that you are running a Gentoo Linux system, as that is what I will be using to build. I also assume that you have the android-sdk-update-manager package installed, and set up properly.
Also, I assume that you have **PLENTY OF DISK SPACE**. Building a tiny gentoo for our phones will require a **LOT** of disk space. We will need to build the system, and rebuild the system, and copy, and so forth.
I will also be assuming that you are familiar with Gentoo systems in general and know your way around them.
We will also be using the XFS file system to create our gentoo image file, so you will either need to have an XFS-capable kernel on your android device, or you will need to use a different file system format that is supported by your android kernel.
Lastly, make sure you have **PATIENCE**. Installing Linux (especially Gentoo, a source-based distro) on an embedded system is time consuming and probably wrought with obstacles.
Now begin by creating a directory where you will perform all of your work:
mkdir ${GENDROID}
cd ${GENROID}
===== Step 1: QEMU, our ARM emulator =====
Although I have successfully installed a stage 3 system directly to the phone AND was able to compile on it, there's no need to be THAT cruel to your phone. Thus, we will be managing our installation from QEMU, an emulator for x86/ARM/PowerPC/etc. This allows us to perform compilations on our computer rather than our phone. Although I have not tested this, I would imagine this would speed things up IMMENSELY.
==== Installation ====
Begin by installing QEMU on your host machine:
You will want the most up-to-date copy of QEMU. Be sure to unmask it (by keyword) in your /etc/portage/package.keywords directory/file. For more information on how to do this search google or view the Gentoo documentation.
USE=static emerge -vb1 qemu-user
==== Set-up our ARM wrapper ====
We are going to need a wrapper to tell our QEMU ARM processor to simulate a cortex-a8 CPU (the Droid CPU). The code is below.
#include
#include
int main(int argc, char* argv[], char* envp[]) {
char *newargv[argc + 3];
newargv[0] = argv[0];
newargv[1] = "-cpu";
newargv[2] = "cortex-a8";
memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc - 1));
newargv[argc + 2] = NULL;
return execve("/usr/bin/qemu-arm", newargv, envp);
}
Save this code and compile it statically:
cd ${GENDROID}
gcc -static qemu-wrapper.c -o qemu-wrapper
==== Load Stage 3 ====
Next we extract our stage 3.
cd ${GENDROID}
tar -jxpvf ${loc_to_download}/stage3-armv7a-20100314.tar.bz2
Lastly we install our ARM reader.
You **NEED** support for binmisc in your kernel for this to work!
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/qemu-wrapper:' > /proc/sys/fs/binfmt_misc/register
ROOT=$PWD/ emerge -K qemu-user
===== Step 2: CHROOT FTW! =====
Now we CHROOT into our ARM root, and from there we will install any applications we wish to run.
==== Enter the CHROOT ====
# mount our portage tree
mkdir -p usr/portage
mount --bind /usr/portage usr/portage
# mount sys/proc
mount --bind /proc proc
mount --bind /sys sys
# gonna need internet
cp /etc/resolv.conf ./etc/
# chroot
chroot . /bin/busybox mdev -s
chroot . /bin/bash --login
env-update
source /etc/profile
export PS1="[arm] $PS1"
==== Update the System ====
Now we are going to go around and update the stage3.
=== Update /etc/make.conf ===
Change your make file to look like the following:
CFLAGS="-Os -fomit-frame-pointer -pipe -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -mtune=cortex-a8"
CXXFLAGS="${CFLAGS}"
CHOST="armv7a-unknown-linux-gnueabi"
MAKEOPTS="-j3"
FEATURES="ccache"
USE="minimal X -cups"
=== Update the System ===
Now we update the system.
emerge -av mirrorselect
mirrorselect -o -t 5 -H -D >> /etc/make.conf
emerge -av ccache eix
emerge -DuavN system
emerge -DuavN world
=== Install any other packages ===
Now we install all of the tools we would like to have. These tools **could** be installed on the phone, but it will be easier to install from a PC (and less strain on your SD card).
# install our window manager/desktop
# (we need to unmask icewm as it has not been tested for ARM)
echo "x11-wm/icewm ~*" >> /etc/portage/package.keywords
emerge -av icewm lxde-meta
# install our VNC server
# (we need to make sure that the server is built)
echo "net-misc/tightvnc server" >> /etc/portage/package.use
emerge -av tightvnc
# install a http server + php + sqlite for shits and giggles
echo "www-servers/lighttpd fastcgi php" >> /etc/portage/package.use
echo "dev-lang/php curl force-cgi-redirect json simplexml sockets sqlite xml zip"
emerge -av lighttpd sqlite php
==== Exit the CHROOT ====
exit
umount usr/portage
umount sys
umount proc
===== Step 3: Create Target Image =====
Now we need to create our image. We will make it 1G in size.
cd ${GENDROID}
dd if=/dev/zero of=gendroid.img bs=1024 count=1048576
mkfs.xfs gendroid.img
Now we rsync our target files to the new XFS file
cd ${GENDROID}
mkdir target_mnt
mount -o loop gendroid.img target_mnt
rsync -av --delete target/ target_mnt/
umount target_mnt
===== Step 4: Copy to Device and Run =====
Lastly, we copy our image to the device, and chroot into it:
cd ${GENDROID}
adb push gendroid.img /sdcard/gendroid.img
adb shell
$ cd /sdcard
$ mkdir gendroid
$ insmod /system/lib/modules/exportfs.ko
$ insmod /system/lib/modules/xfs.ko
$ mount -t xfs -o loop /sdcard/gendroid.img /sdcard/gendroid/
$ mount -o bind /proc /sdcard/gendroid/proc
$ mount -o bind /sys /sdcard/gendroid/sys
$ chroot /sdcard/gendroid /bin/busybox mdev -s
$ chroot /sdcard/gendroid /bin/bash --login
This will get you into a basic CHROOT of your gentoo system. Now you will want to set a few environment variables:
$ env-update && source /etc/profile
$ export USER=root
$ export HOME=/root
$ export TERM=linux
Now when you are done, you can simply exit by:
$ exit
$ umount /sdcard/gendroid/proc
$ umount /sdcard/gendroid/sys
$ umount /sdcard/gendroid
$ losetup -d /dev/block/loop0
$ rmmod xfs
$ rmmod exportfs
Now the above places your system back into its original state.
You might be unable to umount your gentoo image. This is because you may have started some processes that are still running within the chroot. You will have to kill those processes.
===== Appendix A: Cool things to try in CHROOT =====
Below I list some of the fun stuffs I have done with my phone under this environment.
==== Running and LXDE desktop on your phone ====
Ever wanted to run a full desktop on your phone? Well you can! Since you have lxde and icewm installed, it as simple as the following steps.
=== android-vnc-viewer ===
We will technically be doing a local VNC session, so you'll need an adequate viewer.
I am using //android-vnc-viewer//, whose QR code is below.
~~BARCODE~class=barcode_left~url=market://search?q=pname:android.androidVNC~size=S~~
=== setting up LXDE (only needs to be done once) ===
While in the CHROOT of your gentoo installation. Perform the following:
# ensure your home and user
export HOME=/root
export USER=root
# initialize VNC
vncserver -geometry 848x480
At this point you will be asked to enter some passwords. REMEMBER THEM! Really a "view-only" password is not needed.
**YOUR PASSWORDS WILL BE TRUNCATED TO 8 CHARACTERS**
# kill the vncserver after creating the passwords
vncserver -kill :1
# modify startup
cd /root/.vnc
echo '#!/bin/sh' > xstartup
echo 'icewm &' >> xstartup
echo 'lxsession' >> xstartup
chmod 755 xstartup
Now you should be set!
=== start LXDE ===
To start LXDE, simply run
export USER=root
export HOME=/root
vncserver -geometry 848x480
To kill LXDE, run
vncserver -kill :1
# sometimes some stale menu caches sit around
killall menu-cached
=== connect to a running LXDE ===
Now for the magic. While LXDE is running, navigate to your //android-vnc-viewer// app on your phone.
Enter the following information into the connection dialog:
* Nickname - whatever you want
* Password - whatever you chose as a password
* Address - "localhost"
* Port - "5901"
* Color Format - "24-bit color (4 bpp)"
* Local mouse pointer - NO
* Force full screen bitmap - NO
* Repeater - No repeater
Connect an *BAM*! Desktop!
===== References =====
* [[http://www.androidfanatic.com/cms/community-forums.html?func=view&catid=9&id=1615|Gnome/KDE/Etc on Android]] - An awesome example of how to use VNC to run LXDE on a G1 under a debian CHROOT
* [[http://www.gentoo.org|Gentoo]] - Homepage for Gentoo
* [[http://wiki.qemu.org|QEMU]] - Homepage for QEMU
* [[http://www.gentoo.org/proj/en/base/embedded/handbook/?part=1&chap=5|Compiling with QEMU]] - Useful document