Update (May 2014): I’ve since had the occasion to do this again on my Xperia U, and this time I used Linux Deploy to install Ubuntu 14.04 inside Android 4.0.x – it worked flawlessly, and besides having the source available, it has up-to-date presets to download and install the required bootstrap files directly on the phone (no computer required).
To make a long story short, we took a mini-break out in the countryside, and I got bored.
I was supposed to relax and read up on a whole bunch of stuff related to natural language processing, but since I’ve been fiddling around with LXC and
chroot so often these days I decided to have a go at upgrading my Android phone (aka my pocket server) to Ubuntu 13.04.
(In case you missed that post, I’m using the Complete Linux Installer to run a server sandbox off an old Xperia Arc S, and it works well enough for me to run an instance of this site there – and much more besides.)
do-release-upgrade worked fine to step up to 12.10 from 12.04, but the Complete Linux Installer’s supplied images are built with
armel binaries whereas 13.04 has moved on to
armhf exclusively – so after confirming that my Xperia could run
armhf binaries via
multiarch (which, incidentally, made things a tad snappier), I decided to build a new image from scratch.
Regretfully there’s very little info out there on how to go about doing that other than a few scattered forum posts, so I decided to document the process. It’s all fairly straightforward provided you’re using the Complete Linux Installer app already and have a Ubuntu box handy (I daresay it can be done on the phone itself on simpler cases).
sudo apt-get install debootstrap qemu-user-static qemu-system git \ gcc-arm-linux-gnueabihf binfmt-support
Now create the filesystem itself (this is for a 2GB image) and mount it under
/mnt. Since we don’t need all the bells and whistles of
ext4 (after all, the end result will be running inside a file), we’ll be building everything inside an
dd if=/dev/zero of=ubuntu.img bs=1024 count=2097152 mkfs.ext2 ubuntu-armhf.ext2.img sudo mount -o loop ubuntu-armhf.ext2.img /mnt
Next up, use
debootstrap to deploy the basics (note the
HOSTNAME=ubuntu-armhf sudo debootstrap --variant=minbase --foreign \ --arch armhf raring /mnt
qemu-arm-static inside the soon-to-be
sudo cp /usr/bin/qemu-arm-static /mnt/usr/bin/
…and use it to finish the deployment:
LANG=C sudo chroot mnt /usr/bin/qemu-arm-static -cpu cortex-a9 /bin/bash ./debootstrap/debootstrap --second-stage
Once that’s done, we need to set up
apt sources (you can optionally set up
deb-src as well, but I have yet to need it):
echo "deb http://ports.ubuntu.com raring main restricted universe" > /etc/apt/sources.list apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 428D7C01
From then on, you can install stuff as required (this is my base setup):
apt-get update apt-get install sudo apt-utils dialog less wget vim net-tools openssh-server \ htop tmux build-essential libevent-dev python-dev python-setuptools \ python-lxml sqlite3 nodejs npm golang git-core
apt-get install --no-install-recommends tightvncserver
cp /etc/init/tty1.conf /etc/init/ttyAMA0.conf sed -i "s/tty1/ttyAMA0/" /etc/init/ttyAMA0.conf
To top everything off, you need to set up a user with
adduser ubuntu usermod -aG sudo ubuntu
Next up, exit the
Now for the Complete Linux Installer tweak, which boils down to copying across their
init.sh script (of which I’ve made a local copy) to
/root/init.sh and making sure it’s executable3, as well as adding a couple of extra mount points:
sudo cp init.sh /mnt/root/init.sh sudo chmod +x /mnt/root/init.sh sudo rm /mnt/usr/bin/qemu-arm-static sudo mkdir /mnt/sdcard sudo mkdir /dev/shm sudo umount /mnt
Now copy the image across (it should clock in at about 400MB compressed, in case you want to keep a copy around), replace the original Ubuntu image on your SD card, and you’re golden.
I’ve since managed to get Postgres running on mine – just disable TCP and use UNIX sockets instead so that it doesn’t get confused with the network setup.
I’ve tweaked the one I’m actually using a bit further, since I need
/dev/shmto work. Also, I wish they’d document the configuration files somewhere – I’d also like to have custom mounts working without hacking them into the script. ↩︎