Debian GNU/Linux on the Google Nexus S


This article describes how to get Debian GNU/Linux running in a chroot environment on the Google Nexus S mobile phone. To put this information together I used various online sources, particularly helpful was the guide at http://http://evilzone.org/android/debian-on-android/. The installation involves the following steps that will be explained in detail below:


Make a backup

The procedure will erase all data (such as apps, phone numbers, messages, pictures etc.) from the phone. Before starting, make a backup. There are various backup utilities for Android, I only needed to backup my contacts, for this purpose I was happy with vcardio.


Obtain adb and fastboot

In order to unlock the phone and install the ClockwordMod recovery image you will need the fastboot tool. Follow the instructions of the Android Wiki to obtain fastboot (the easiest way is to download the precompiled x86 binary). Later in the installation you will need the adb tool. Simply download Google's Android SDK, install it according to the instructions and find adb in the platform-tools subdirectory.
Now create the directory ~/nexuss-debian:

mkdir ~/nexuss-debian/
Copy adb and fastboot into this directory.

Unlock (root) the phone

In order to unlock the phone, first switch it off, then reboot it by holding the volume-up and the power button. This will boot the phone into the fastboot mode. Now connect the phone with a USB cable to computer and first make sure that fastboot finds the phone:

cd ~/nexuss-debian/
./fastboot devices

If the output of this command is empty, your phone was not found, try running fastboot as root or try restarting udev by running

/etc/init.d/udev restart

Once your phone is found by fastboot, unlock the phone by running

./fastboot oem unlock

Install the ClockworkMod recovery image (5.0.0.0)

Download the latest ClockwordMod recovery image from the "Google Nexus S" link on the ClockworkMod recovery images list. For me the version was 5.0.0.0 (filename recovery-clockwork-5.0.0.0-crespo.img). Place the file in the ~/nexuss-debian directory. Again boot into the fastboot menu and confirm that the device is found by fastboot (see previous step) and then run

cd ~/nexuss-debian/
./fastboot flash recovery recovery-clockwork-5.0.0.0-crespo.img

Of course replace recovery-clockwork-5.0.0.0-crespo.img with the name of the file downloaded.


Install CyanogenMod (7.1.0)

Download the latest CyanogenMod image from the CyanogenMod Nexus S website. We assume in the following that the version is 7.1.0 (filename update-cm-7.1.0-NS-signed.zip). Copy this file to the internal SD card of the phone, for example by connecting it to the computer via USB, exporting the SD card as USB mass storage, (Select the "USB connected" note and click on "Turn on USB storage") and then copying the file to the root directory of the USB device appearing on your computer.
Now reboot your phone again into the fastboot mode (see above), select "Recovery" (using the volume-down button, power-button to confirm) and then select "backup and restore" and then "Backup" to make a backup of the current system.
Now choose "install zip from sdcard", then "choose zip from sdcard" and then choose the CyanogenMod zip file update-cm-7.1.0-NS-signed.zip. This will install CyanogenMod on your Nexus S.


Create the Debian image

To create a Debian ARM image first do the following on a computer with Debian (or Ubuntu) installed (as root):

aptitude install debootstrap debian-archive-keyring debian-ports-archive-keyring
cd ~/nexuss-debian
dd if=/dev/zero of=debian.img bs=1MiB count=4000
mkfs.ext3 debian.img
mkdir debian
mount -o loop debian.img debian/
debootstrap --arch armel --foreign --verbose squeeze debian http://ftp.us.debian.org/debian
umount debian

This will install debootstrap, then create a 4000MB image, format this image with ext3 and perform a stage-one debootstrap Debian installation inside this image (stage-two will be done on the phone in the next step).
Of course you can choose a different size for the image, but make sure that the size is smaller than 232-1 bytes (about 4GB), the maximal file size supported by the FAT32 file system on the phone.


Set up Debian on the phone

To set up Debian on the phone first make sure that USB debugging is enabled. This can be found in the Settings under Applications – Development – USB Debugging. I also enabled "Allow mock locations" and "stay awake" in the same menu.
Now connect your phone through the USB cable to the PC and make sure that adb finds your device. Run (as root):

./adb devices

This should output something like
35337508A20300EC device
If it does not output anything your mobile is not detected. What may help is disconnecting the USB cable, restarting udev through

/etc/init.d/udev restart
and then connecting the phone again. When the phone has been detected you can copy the Debian image to the phone:
cd ~/nexuss-debian
./adb push debian.img /mnt/sdcard/

Now execute a shell on the phone, create a loop device, mount the image, chroot into the Debian system, and run the second stage of the installation

./adb shell
mkdir /data/local/debian/
losetup /dev/block/loop0 /sdcard/debian.img
busybox mount /dev/block/loop0 /data/local/debian
busybox chroot /data/local/debian /bin/bash
export PATH=/usr/bin:/usr/sbin:/bin:$PATH
export TERM=linux
export HOME=/root
export USER=root
/debootstrap/debootstrap --second-stage

After this second stage of the installation has finished, first set the password for root (still on the shell with chroot to the Debian system)

passwd root

and set up DNS servers and the hostname:

echo "nameserver 4.2.2.2" > $mnt/etc/resolv.conf
echo "nameserver 8.8.8.8" >> $mnt/etc/resolv.conf
echo "nameserver 8.8.4.4" >> $mnt/etc/resolv.conf
echo "127.0.0.1 localhost" > $mnt/etc/hosts

As next steps I recommend to do the following (still on the shell with chroot to the Debian system):

echo "deb http://ftp.de.debian.org/pub/debian/ stable main contrib non-free" > /etc/apt/sources.list
echo "deb-src http://ftp.de.debian.org/pub/debian/ stable main" >> /etc/apt/sources.list
echo "deb http://security.debian.org/ stable/updates main contrib non-free" >> /etc/apt/sources.list
echo "deb-src http://security.debian.org/ stable/updates main contrib" >> /etc/apt/sources.list
aptitude update
aptitude install locales
aptitude install ssh
echo "#!/bin/bash" > /etc/init.d/chroot_start.sh
echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /etc/init.d/chroot_start.sh
echo "/bin/mount -t proc proc /proc" >> /etc/init.d/chroot_start.sh
echo "/bin/mount -t devpts devpts /dev/pts" >> /etc/init.d/chroot_start.sh
echo "/bin/mount -t sysfs sysfs /sys" >> /etc/init.d/chroot_start.sh
echo "hostname nexuss" >> /etc/init.d/chroot_start.sh
echo "/etc/init.d/ssh start" >> /etc/init.d/chroot_start.sh
chmod 755 /etc/init.d/chroot_start.sh
exit

After each reboot of the phone you can now "boot" Debian by connecting from your computer through

cd ~/nexuss-debian/
./adb shell

in the same way as above and in this shell entering

mkdir -p /data/local/debian/
losetup /dev/block/loop0 /sdcard/debian.img
busybox mount /dev/block/loop0 /data/local/debian
busybox chroot /data/local/debian /etc/init.d/chroot_start.sh

Accessing the CPU's cycle counter

Daniel J. Bernstein wrote a guide on how to access the cycle counter on a Cortex A8 CPU. The baseline is that a kernel module is required and this in turn requires the kernel sources of the system. I have not been successful finding the configuration of the running CyanogenMod kernel so I resorted to installing a netarchy kernel, in my case I downloaded the file netarchy-nexus-1.3.9-cfs-universal-signed.zip. The installation procedure is the same as for the CyanogenMod image (see above), however, it is recommended to "wipe cache partition" and "Wipe Dalvik Cache" (under "advanced") from the Recovery menu.
After rebooting the phone, and "booting" the Debian system, ssh into Debian and download and prepare the kernel sources (as root):

cd /usr/src/
git clone git://github.com/netarchy/nexus-s.git
cd nexus-s
cp /proc/config.gz .
gzip -d config.gz
mv config .config
make oldconfig
make prepare && make modules_prepare

Now install and load the enableccnt module following Dan's guide.
Alternatively you can download and use my precompiled enableccnt.ko module. The md5 checksum of the file is 9d764cfd8c435833b20fcadfcbc5051a.