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:
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:
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
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
/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.
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; else bootm 0x48000000; fi
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.