From standard install to Fatdog-style install
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:
- RAM layer for pure SD card solution
- Unlimited swap and root fs on external USB drive configured at boot
- Network filesystem
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:
- Visit http://aufs.sourceforge.net/ and clone the "aufs3 standalone" repository.
- Follow the patch instruction on that page (use "aufs3.0" branch). Build aufs as a built-in (do not build as a module).
- 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
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
/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
- 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.
- Second, copy the uInitrd --- also to the FAT partition
- 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; 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):
- There is 16 KB static RAM at the beginning of the address space (0), usually used to non-reroutable interrupt vectors. We can happily ignore this.
- Main memory (DRAM) starts at 0x40000000 and ends at 0x5FFFFFFF (that is, it spans 0x20000000 bytes starting at 0x40000000).
- Some of this are reserved by the Mali GPU, the Cedar Video Engine (VE), and the 2D graphics accelerator (G2D).
- U-boot loads kernel at 0x48000000 but will relocate it to 0x40008000 before starting it (the kernel will execute with virtual address of 0xC0008000).
- Kernel expects to find hardware confguration at 0x43000000
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.