Saturday, June 29, 2013

0x0004


DISCLAIMER:
I am NOT responsible if you break your OUYA, and probably will not have time to walk you through fixing it if something goes wrong. If you have no idea what half of this means, don't try it!

TL;DR: Scroll down to see the instructions. 




When I heard of the OUYA, I wasn't interested in the games, but more so of the fact that it's a $100 ARM device with a quad-core tegra 3 and 1 GB of ram. It has the specs of a modern $600 android phone, at a fraction of the cost. I ordered one with the intention of installing the Debian operating system, and to have a cute 3 inch cube server!

Right now I have a Debouya box running perfectly. If you want to do the same, here's how.

The first obstacle to get through was that I needed chroot. chroot is a binary that locks your current shell into a "chroot jail", with a different apparent root. For example, I could create a directory /home/newroot and copy a Debian system into it, then chroot in and everything running from that will share that fake root. This is what we'll be doing with Debian, and the same way that other people have installed other Linux distros on their Android phones. Android, by the way, already has a very slightly modified Linux kernel, but for practical purposes you won't notice a difference (the main difference is the HAL or hardware abstraction layer between the kernel and sensor interface to apps).

Busybox is a program which is a set of common *nix binaries, stripped down, like ls, cp and chroot. For some reason the OUYA doesn't have a few of these, or they didn't work as expected.

Thankfully, I didn't have to cross-compile any of these for the OUYA. I already had it on my Galaxy S3, so I just pulled busybox out and copied it the OUYA. For some reason, it couldn't link the function strlen from the stock libc.so in the OUYA, so I copied that out as well. The environment variable LD_LIBRARY_PATH will be where programs look to access shared code from dynamically-linked libraries (SOs in linux, DLLs in windows, dylibs in MacOS), so I copied the libc.so from my S3 over as well and called busybox while setting the LD_LIBRARY_PATH to a directory I copied the other libc.so too. Make sure you don't write over your other one in /system/lib! Another option is to place it in /vendor/lib which is another path in LD_LIBRARY_PATH on your OUYA, which I did, so it automatically links to it when running busybox.

Then, I used debootstrap to copy a base debian system into a flash drive, which I will mount later and chroot into. From there, we'll have our working Debouya!

BEFORE YOU GET STARTED, YOU'LL NEED:

LET'S GET STARTED:

The first step is to install clockworkmod on your OUYA
You should have installed the Android SDK, and find the program adb

Now, get a shell into your OUYA. 
adb shell
Inside that shell:
su
mount -oremount,rw /dev/block/platform/sdhci-tegra.3/by-name/APP /system
mkdir /usb_drive
mount -oremount,rw rootfs /
echo "1" > /proc/sys/net/ipv4/ip_forward
Back to your computer. First extract the busybox and libc.so from the tar.gz I linked to above.
adb push busybox /system/bin
adb push libc.so /vendor/lib
You may need to fix permissions to do this. If you have this problem, do this from inside adb shell:
chown root:sdcard_rw /system/bin
chown root:sdcard_rw /vendor/lib
Now pop your USB drive into your computer, so we can bootstrap debian onto it. I had mine formatted with ext4, which you should probable do as well with mkfs.ext4 /dev/whatever_block_device_it_is
export PATH_TO_DRIVE=/media/YOUR_USB_DRIVE
mkdir $PATH_TO_DRIVE/debian
sudo debootstrap --arch=armel --variant=minbase --foreign wheezy $PATH_TO_USB_DRIVE/debian http://http.debian.net/debian
Now you've got a debian base system in the drive under the directory debian!
Unmount the flash drive, pull it out and pop it into your OUYA. Now we mount it and chroot into it to run the second stage.

Insert your flash drive into the OUYA. Check dmesg, but it should go to /dev/block/sda. For some reason, I didn't see /dev/block/sda1, but fixed it by doing:
busybox mount /dev/sda /usb_drive     (which failed) then
busybox mount /dev/sda1 /usb_drive   (which worked??) 
Okay, we're almost there. Now you should have your usb drive mounted in /usb_drive, and have the subdirectory debian with the debian filesystem. 
Back to your adb shell:
mount -t proc none /usb_drive/debian/proc/
mount -t sysfs sysfs /usb_drive/debian/sys/
mount -t devpts devpts /usb_drive/debian/dev/pts
busybox chroot /usb_drive/debian /bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
debootstrap/debootstrap --second-stage (this will take a bit)
echo "deb http://ftp.us.debian.org/debian/ wheezy main contrib non-free" > /etc/apt/sources.list
echo "deb http://security.debian.org/ wheezy/updates main contrib non-free" >> /etc/apt/sources.list
echo "8.8.8.8" > /etc/resolv.conf
echo "8.8.4.4" >> /etc/resolve.conf
hostname some.cool.hostname
apt-get update
apt-get install all_your_cool_new_programs
If you aren't connected to the internet, but plugged in through ethernet, try:
ifconfig eth0 up
dhcpd
I forget if this is from the chroot or inside adb shell, but I think from inside adb shell. You can always open a new shell to do this without exiting the chroot (ctrl-D to do that, by the way).

When you turn off your ouya and boot it back up, you should have to repeat some of these steps, most likely anything that starts with "mount". You will need to make the /usb_drive dir, mount the flash drive into it, mount all your virtual filesystems like proc sys and devpts, and then chroot back in. You will have to export your PATH again as well. It's relatively quick, and you can easily write a shell script to handle it.

Helpful links which got me through this:
http://www.mayrhofer.eu.org/debian-on-android
http://rubiojr.rbel.co/hack/2013/01/10/installing-arch-linux-in-your-android-phone-chroot/
http://wiki.debian.org/ChrootOnAndroid

By this point, you should have a working debian system! Let me know if I'm missing something.
Cheers!

3 comments:

  1. in shell after su and the remount of systems are your supposed to change to system dir cuz i keep getting
    and@ouya:~/android/sdk/platform-tools$ adb shell
    shell@android:/ $ su
    platform/sdhci-tegra.3/by-name/APP /system <
    shell@android:/ # mkdir /usb_drive
    mkdir failed for /usb_drive, Read-only file system

    ReplyDelete
  2. You probably need to remount your root drive. I'll check it out later and let you know

    ReplyDelete
  3. echo "8.8.4.4" >> /etc/resolve.conf should be echo "8.8.4.4" >> /etc/resolv.conf

    ReplyDelete