Cross debootstrap Debian Root Filesystem with User Mode QEMU

Many platforms exist out there where a simple boot floppy, CD or USB key approach to installation is unavailable, the majority of these systems are non-x86 based and can be very unfamilar to a lot of experienced Linux users. These instructions detail how on your own x86 based workstation you can build a Debian root filesystem in a familar manner for a non-x86 (foreign target) CPU architecture such as ARM, MIPS, SPARC, etc. Two things to bear in mind when blindly using these instructions:

The only packages you need to install are:

N.B. alas everything here needs to run as root, so be careful with what you type.

Creating the Root Filesystem

'debootstrap' is a tool used to create standalone Debian based root filesystems, however it also has a rather nice handy feature that it can build root filesystems for foreign CPU architures too. This means you can build an ARM or MIPS based root filesystem entirely on a x86/amd64 based workstation. There are two stages to 'debootstrap', the first stage runs without problems and no need for trickery:

berk:/usr/src/kirkwood# debootstrap --verbose --foreign --arch=armel --variant=minbase --include=module-init-tools,locales,udev,aptitude,dialog,ifupdown,procps,iproute,iputils-ping,pump,nano,wget,netbase squeeze rootfs
I: Retrieving Release
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Found additional required dependencies: insserv libbz2-1.0 libdb4.8
I: Found additional base dependencies: debian-archive-keyring gnupg gpgv libboost-iostreams1.42.0 libcwidget3 libept1 libncursesw5 libpopt0 libreadline6 libsigc++-2.0-0c2a libsqlite3-0 libssl0.9.8 libudev0 libusb-0.1-4 libxapian22 net-tools readline-common
I: Checking component main on
I: Retrieving libacl1
I: Extracting xz-utils...
I: Extracting zlib1g...

You now have the base stage one root filesystem in place with all the necessary required Debian packages for that architecture downloaded and a number of which have been extracted. The idea is that you now continue onto stage two by copying (some how, this is usually the very complicated step and can even be rather catch-22) in nature) everything to your target platform and continuing from there. There is a better way though, qemu supports a lesser know feature known as 'user mode emulation' which lets you natively execute foreign (eg. ARM, MIPS, etc) binaries as if they were compiled for your host CPU architecture (typically x86 or amd64). Using this is simply a case of calling upon the binfmt_misc kernel module and the statically compiled version of the qemu usermode emulation binaries:

berk:/usr/src/kirkwood# cp /usr/bin/qemu-arm-static rootfs/usr/bin/
berk:/usr/src/kirkwood# chroot rootfs
I have no name!@berk:/# ./debootstrap/debootstrap --second-stage
I: Installing core packages...
I: Unpacking required packages...
I: Unpacking libacl1...
I: Configuring aptitude...
I: Base system installed successfully.
I have no name!@berk:/# apt-get clean
I have no name!@berk:/# dpkg-reconfigure tzdata
I have no name!@berk:/# dpkg-reconfigure locales
I have no name!@berk:/# passwd
I have no name!@berk:/# exit
berk:/usr/src/kirkwood# rm rootfs/usr/bin/qemu-arm-static

N.B. as an interesting check for yourself, you might want to compare the output of "uname -a" before and after the 'chroot' command plus the output of file /bin/sleep rootfs/bin/sleep

Now your Debian rootfs is complete, however it actually needs some tweaking to make it usable. These following commands remove un-necessary files, lift handy hints from a page I read on Installing Debian on the Sheevaplug and prime up aptitude in the rootfs so that it is ready to go:

berk:/usr/src/kirkwood# find rootfs/var/lib/apt/lists -type f -delete
berk:/usr/src/kirkwood# rm -r rootfs/dev/.udev
berk:/usr/src/kirkwood# : > rootfs/etc/hostname
berk:/usr/src/kirkwood# : > rootfs/etc/resolv.conf
berk:/usr/src/kirkwood# ln -s /dev/null rootfs/etc/
berk:/usr/src/kirkwood# ln -s /proc/mounts rootfs/etc/mtab
berk:/usr/src/kirkwood# : > rootfs/etc/udev/rules.d/70-persistent-net.rules
berk:/usr/src/kirkwood# echo 'APT { Install-Recommends "false"; };' > rootfs/etc/apt/apt.conf.d/no-recommends
berk:/usr/src/kirkwood# sed -i -e '/^RAM\(RUN\|LOCK\)=/ s/^\(.*\)=.*$/\1=yes/' rootfs/etc/default/rcS

berk:/usr/src/kirkwood# cat `<<EOF >` rootfs/etc/hosts       localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

berk:/usr/src/kirkwood# cat `<<EOF >` rootfs/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback
#iface lo inet6 loopback

berk:/usr/src/kirkwood# cat `<<EOF >` rootfs/etc/fstab
# /etc/fstab: static file system information.
# `<file system>` `<mount point>`   `<type>`  `<options>`                     `<d>``<p>`
/dev/root       /               auto    relatime                       0  0

tmpfs           /tmp            tmpfs   nodev,nosuid,noexec,size=32M   0  0
tmpfs           /var/tmp        tmpfs   nodev,nosuid,noexec,size=8M    0  0

berk:/usr/src/kirkwood# cat `<<EOF >` rootfs/etc/apt/sources.list
deb squeeze main contrib non-free
#deb-src squeeze main contrib non-free

deb squeeze/updates main contrib non-free
#deb-src squeeze/updates main contrib non-free

deb squeeze-updates main
#deb-src squeeze-updates main

Now edit the following files to your liking: