====== 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