From standard install to Fatdog-style install

This article argues the need for initrd and then goes on to highlight the steps required to do so.

Why the need?

Using an initrd gives us flexibility. It enables us to do things before the main filesystem is mounted: enable network stack so that we can use a remote network filesystem as our root, for example. It also enables us to do stuff like fsck-ing the filesystem before mounting, etc.

This is especially important because in Mele (and many embedded systems), the boot loader isn't readily accessible for tinkering (this is unlike GRUB loader or syslinux which provide pre-boot environment for the users to enter boot commands, select menus e.g. to choose which kernel to use, etc). Initrd can be used to a lesser extent to provide similar functionality.

For this experiment, I will use ready-made, proven initrd from Fatdog64.

Using Fatdog64 initrd gives us instant benefit of running with Fatdog-style (aka Puppy-style frugal) install:

Building kernel with AUFS

There are only two requirements for using Fatdog64 initrd:

The first one is easy since Squashfs has been merged to mainline kernel long ago (2.6.29 for the latest version). All that is needed is enable it in "Miscellaneous Filesystem" section, in kernel configuration.

The second one requires patching, but it isn't too bad either as it turns out that linux-sunxi 3.0 kernel is "vanilla" enough that aufs patches can be applied without changes:

  1. Visit and clone the "aufs3 standalone" repository.
  2. Follow the patch instruction on that page (use "aufs3.0" branch). Build aufs as a built-in (do not build as a module).
  3. Don't forget to re-configure your kernel to enable aufs.

Optionally, you can also follow the instructions on how to build aufs-utils: mainly contains mount.aufs and umount.aufs; these two mount helpers are used to maintain a persistent hardlinks between reboots. If you don't use hardlinks then they are not necessary. Remember to build them with aboriginal cross compiler if you decide to build them.

Once you have patched the kernel, all you need is to rebuild it and the modules, then installed it to the output directory inside kernel source, then compress the modules into a squashfs file, like this:

make uImage modules
make modules_install INSTALL_MOD_PATH=output
mksquashfs output kernel-modules.sfs -comp xz
Note: only use "-comp xz" if you enable "xz" compression in your kernel configuration.

Preparing Initrd

Get Fatdog64 initrd from somewhere. I'm assuming that you're building this on Fatdog64 so you already know where to get it; if you don't, then just get Fatdog64 ISO, and extract it - it's the file aptly named initrd.

Unless you enable a lot of applets in your original busybox in the FirstBoot steps, you will need to re-configure and re-build busybox again. If you are running Fatdog64, it's easy, run busybox bbconfig and it will give you a .config file you can use to configure your new busybox. Make sure it is static (use aboriginal cross compiler). (If you can't run Fatdog64, see here.

When you have your busybox:

mkdir /tmp/initrd-root
cd /tmp/initrd-root
cpio -i < /path/to/fatdog-initrd         # extract contents of initrd
rm fd64-*.sfs                            # remove Fatdog's base SFS
cp /path/to/linux-sunxi/kernel/kernel-modules.sfs .
cp /path/to/compiled/busybox bin/busybox
rm sbin/init                             # remove original init binaries
ln -s ../bin/busybox sbin/init           # replace it with new busybox's init
rm usr/bin/sdparm sbin/lvm sbin/mdadm    # remove these binaries too
find . | cpio -o -H newc > ../initrd     # re-pack initrd
cd ..
mkimage -A arm -O linux -T ramdisk -d initrd uInitrd. # convert to u-boot's format
And you will have your new initrd in as /tmp/uInitrd. There are other binaries in initrd, you can consult its README to see what they are, and if you're so inclined you can build ARM version of those binaries and replace them too - but what I explained above is the *minimum* necessary.

How to use the initrd

  1. Firstly, you need to use the new kernel. Copy the uImage from /path/to/linux-sunxi/kernel/arch/arm/boot/uImage to the FAT partition.
  2. Second, copy the uInitrd --- also to the FAT partition
  3. Lastly, you will need to edit your boot.cmd to tell it to load the uInitrd. The modified boot.cmd should look like this:
    fatload mmc 0 0x43000000 script.bin
    fatload mmc 0 0x48000000 uImage
    if fatload mmc 0 0x43100000 uInitrd; then
    	bootm 0x48000000 0x43100000;
    	bootm 0x48000000;
    Remember to re-create your boot.scr after you change boot.cmd. Basically that that boot.cmd means is to try to load uInitrd to address 0x43100000, and if it works then used it, otherwise don't use it.

    This way, you can use the same boot.cmd with or without initrd.

That's all - next step is to boot the SD Card and see if it uses the initrd. If it does, you will be greeted with a login prompt. Login as root user, without password.

Note: Unlike in the desktop, where the boot loader (grub or syslinux) decides where to load initrd, here with u-boot we have to determine the address ourselves, for example, I loaded it at physical address 0x43100000. This requires us to know the intricate memory map used by *both* the SoC and the board; because you can't just load it to any arbirtrary location and expect it to work :(

For Mele A1000 (512 MB):

Note: We loaded initrd at 0x43100000, because I disable Mali, VE and G2D modules when I boot so that I can use more memory (I can use up to 504MB out of that 512MB; if I enable all these stuff I only have 320MB free - yuck!) If you enable them you may need to load initrd elsewhere (0x50000000 sounds good too).

Next: Going Native

Building busybox for Fatdog initrd

Fatdog initrd expects a rather complete collections of applet in busybox; and as well as the guess_fstype binary from here (password needed - check Puppy Linux forum for it). If you can't get the configuration from Fatdog64's busybox, then use the following configuration and patches. The patches is against git version of busybox, commit 6651e4260955d159e6a4f794d0a69c1b3f8e670c.

The patch fix a minor problem with awk and md5sum; and will also create guess_fstype applet.

Note that the configuration above includes way more applets than what is minimally needed for Fatdog initrd.