Setting up a sunxi board with a ramdisk and ATA over Ethernet rootfs boot

This setup has been tested with the Olimex A20 Lime2 and microsd cards.

Creating and filling the ramdisk

First let's create our initial ramdisk that will be 8M big. Format it, and mount it:

# dd if=/dev/zero of=initrd.img bs=1k count=8192
# mke2fs -vm0 initrd.img 8192
# tune2fs -c 0 initrd.img

# mkdir mnt
# mount -o loop initrd.img ./mnt

After we've done this, let's setup the fs hierarchy we'll be using:

# cd mnt
# mkdir -p bin dev/etherd etc mnt/root proc sys tmp usr
# chmod 1777 tmp
# touch etc/fstab

We also need /dev nodes inside it.

# cp -a /dev/console /dev/null /dev/random /dev/tty /dev/urandom dev/

And let's add add a statically linkedbusybox:

# cp /bin/busybox bin
# busybox --install -s ./bin

Add more files as needed. To boot AoE, we need aoetools. Find them here: https://github.com/OpenAoE/aoetools

Finally, we need an init script that will set up the things needed and switch root once mounted. The following scripts implies an available AoE mount at /dev/etherd/e0.1p1. It also implies having a directory called old_root in that rootfs.

#!/bin/busybox sh

rescue_shell() {
    echo "$@"
    echo " * dropping to a shell"
    exec /bin/sh
}

ifconfig eth0 up || rescue_shell

mount -t sysfs none /sys
mount -t proc  none /proc
echo 0 > /proc/sys/kernel/printk
sleep 2

echo " * discovering AoE block devices"
/usr/sbin/aoe-discover
sleep 3
/usr/sbin/aoe-discover
sleep 3

echo " * mounting AoE root"
mount -t ext4 -o ro /dev/etherd/e0.1p1 /mnt/root || rescue_shell

echo " * mounting to /mnt/root"
mount -t devtmpfs none /mnt/root/dev
mount -t sysfs none    /mnt/root/sys
mount -t proc none     /mnt/root/proc

echo 1 > /proc/sys/kernel/printk

echo " * pivoting root"
cd /mnt/root
pivot_root . old_root || rescue_shell "Failed pivoting"
umount /old_root/proc /old_root/sys /old_root/dev

echo " * exec-ing init"
exec /sbin/init 3 || rescue_shell "init failed"

Kernel config

To use this setup, our kernel needs the following:

#
# General setup
#
...
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
...

#
# UBI - Unsorted block images
#
...
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
...

U-Boot

For u-boot, we have to make an uInitrd out of the initrd.img we've previously created. This can be achieved with the following:

# mkimage -A arm -T ramdisk -C none -n uInitrd -d /path/to/initrd.img /path/to/uInitrd

Copy this to the microsd card or push it in FEL mode.

If we're doing the microsd card boot, we can use a boot.scr like the following:

setenv bootargs console=ttyS0,115200 root=/dev/ram0 ro rootwait
load mmc 0 0x43000000 ${fdtfile}
load mmc 0 0x41000000 zImage
load mmc 0 0x50000000 uInitrd
#setenv initrd_high 0xffffffff
bootz 0x41000000 0x50000000 0x43000000

Convert to boot.scr:

# mkimage -A arm -T script -C none -d boot.cmd boot.scr

Resources