Setting up UNIONFS
Ok, so one thing that was unfortunate about all of this is that we pretty much have to make a choice: in Debian, or in Android. This is the kind of choice we really shouldn't have to make, especially given that the two systems pretty much don't overlap. This is where unionfs comes in.
Note that all commands from here on are being executed outside of the Debian chroot we entered earlier, so still over telnet. You can exit with exit or just open a new telnet session. You can then download these commands as a ready-made script.
To run this ready-made script you should already have exported your standard environment variables. If you have the script in your $kit, then you can run it as so with . (so you can avoid issues regarding noexec on /sdcard).
. $kit/unionfs
busybox insmod $kit/unionfs.ko mount -t unionfs -o dirs=$mnt/etc=rw:/etc=ro unionfs /etc
What this does is make /etc contain both the files from Android and the files from Debian. It also sets the system up so that if we modify any files in /etc (or create any new ones) these modifications will get stored in our Debian partition: a feature that now gives us a fully working /etc!
The next problem is that Android and Linux use different naming conventions for their dynamic linker. On Android we have /system/bin/linker, whereas on Linux we have /lib/ld-linux.so.3. This means we get file not found errors just from running valid software. This is easy enough to fix with a symlink.
mount -o remount,rw /
ln -s $mnt/lib /
At first glance this might seem dangerous, but it isn't. While we are modifying the root filesystem of the device (something we aren't supposed to be able to do), it happens to be rootfs: a special instance of the Linux ramfs filesystem. This means that any changes we make to it are undone by a simple reboot.
At this point we should be able to run most Debian programs without entering a chroot by just running the program from $mnt. Unfortunately, not everything is going to work as most of the files are in the wrong place. Let's fix that with some more symlinks.
for x in bin boot home media mnt opt selinux srv usr var do
ln -s $mnt/$x / done
This leaves only a few folders that we need to deal with. The first one is trivial: /root is empty, so we can just get rid of it and replace it with another symlink. Also, as we are now done modifying the filesystem on /, I highly recommend reprotecting this mount as files that end up here directly take up RAM (not flash) and do not get sync'd back to the Debian environment (which is confusing/wrong).
rmdir /root
ln -s $mnt/root /
mount -o remount,ro /
This leaves /sbin and /dev. The former can be handled by a simple unionfs, but the situation with /dev is actually pretty evil. It has a mount underneath it, /dev/pts, that you seemingly can't layer under a unionfs for whatever reason and expect it to still work. The fix for this is to remount it back on top after the union.
mount -t unionfs -o dirs=$mnt/sbin=rw:/sbin=ro unionfs /sbin mount -t unionfs -o dirs=$mnt/dev=rw:/dev=rw unionfs /dev mount -t devpts devpts /dev/pts
At this point we have everything setup well enough that even things like OpenSSH should work, so let's restart it in this environment.
/etc/init.d/ssh restart