It works pretty wel, were it not for the problem with sdcard corruption that seems to keep coming back. The quality of the SD card,the power adapter and clockspeeds affect the chance of sdcard corruption. I've experimented with different sdcards, power adapters and downclocking memory and cpu, but corruption still occured.
Using a more "flash friendly" fileystem would probably help. f2fs looks very promising, performance is really good (I need to look into that at another time.)
Currently I am using AUFS (a union filesystem), I use it to mount both a tmpfs and the sdcard rootfs on the root of the directory hierarchy.
The sdcard rootfs is mounted ro, all writes go to tmpfs. Since all writes are now send to RAM all changes are non-persistant, this way there's almost zero chance on SD card corruption. If changes need to be persistant or if to much RAM gets eaten, you should use a storage device as rwfs instead of tmpfs. It doesn't have to be local, nfs or sshfs should also work.
Configuring AUFS is pretty easy, though you'll need recompile your kernel with it. You should use a crosscompiler because on the pi it would take ages.
For the most part I used this post which has a nice init script for initramfs. There were a few things that didn't work for me because the post is slightly outdated so I changed it a bit. (for instance aufs3-mmap.patch is replaced with aufs3-proc_map.patch since 3.8) If you are using the example below you should change the git version branches that are being used, so they match your kernel version. Als check the variables, you might have to change them if they are not relevant for you. In the DEVPC part I assume ubuntu x64 is being used, if you're using x86 you should remove the x64 part in the CCPREFIX variable.
RPI:
# temporarily install busysbox and e2fscksudo apt-get -y install busybox-static e2fsck-static
mkdir initramfs
cd initramfs
# create required directories
mkdir -p aufs bin dev etc lib proc rootfs rw sbin sys usr/{bin,sbin}
touch etc/mdev.conf
# populate dev
sudo mknod -m 622 dev/console c 5 1
sudo mknod -m 622 dev/tty0 c 4 0
# install busybox
cp /bin/busybox bin/
ln -s busybox bin/sh
# install e2fsck
cp /sbin/e2fsck.static sbin/e2fsck.static
#don't copy this manually into init, variables are escaped so they don't expand while redirecting output to init
cat > init <<EOF
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/bin/busybox --install -s
# create mtab so that fsck won't complain
/bin/ln -sf /proc/mounts /etc/mtab
# wait for slow sdcards
/bin/sleep 5
# populate /dev
/sbin/mdev -s
ROOTDEV=""
ROOTFSTYPE="ext4"
ROOTFSOPTS="noatime"
RWFS=""
RWFSTYPE=""
RWFSOPTS="noatime"
AUFS=false
AUFSCK=false
for x in \$(/bin/cat /proc/cmdline); do
case \$x in
root=*)
ROOTDEV=\${x#root=}
;;
rootfstype=*)
ROOTFSTYPE=\${x#rootfstype=}
;;
rootfsopts=*)
ROOTFSOPTS=\${x#rootfsopts=}
;;
rwfs=*)
RWFS=\${x#rwfs=}
;;
rwfstype=*)
RWFSTYPE=\${x#rwfstype=}
;;
rwfsopts=*)
RWFSOPTS=\${x#rwfsopts=}
;;
aufsck)
AUFSCK=true
;;
esac
done
# check root device
if [ ! -b "\${ROOTDEV}" ]; then
echo "Root partition \${ROOTDEV} missing"
exec /bin/sh
exit 0
fi
# fsck root partition
echo "Checking root partition \${ROOTDEV}"
/sbin/e2fsck.static -y \${ROOTDEV}
# mount root
echo -n "Mounting root partition \${ROOTDEV} "
mount -t \${ROOTFSTYPE} -o ro,\${ROOTFSOPTS} \${ROOTDEV} /rootfs
if [ \$? -ne 0 ]; then
echo "failed"
exec /bin/sh
exit 0
else
echo "OK"
fi
# check for rw partition
if [ "\${RWFS}" = "tmpfs" ]; then
RWFS="aufs-tmpfs"
RWFSTYPE="tmpfs"
RWFSOPTS="rw"
else
if [ ! -b "\${RWFS}" ]; then
echo "RW partition \${RWFS} missing"
RWFS=""
fi
fi
if \${AUFSCK} && [ -b "\${RWFS}" ]; then
# fsck rw partition
echo "Checking RW partition \${ROOTDEV}"
/sbin/e2fsck.static -y \${RWFS}
fi
if [ -n "\${RWFS}" ]; then
# mount rw partition
echo -n "Mounting RW partition \${RWFS} "
mount -o \${RWFSOPTS} -t \${RWFSTYPE} \${RWFS} /rw
if [ \$? -ne 0 ]; then
echo "failed"
AUFS=false
else
echo "OK"
AUFS=true
fi
else
AUFS=false
fi
if \${AUFS}; then
# mount aufs partition
echo -n "Mounting AUFS "
mount -t aufs -o dirs=/rw:/rootfs=ro aufs /aufs
if [ \$? -ne 0 ]; then
echo "failed"
AUFS=false
else
echo "OK"
fi
fi
if \${AUFS}; then
# mount aufs as root partition
# test for mount points on aufs file system
[ -d /aufs/ro ] || /bin/mkdir /aufs/ro
[ -d /aufs/rw ] || /bin/mkdir /aufs/rw
# move RO and RW inside aufs
mount --move /rw /aufs/rw
mount --move /rootfs /aufs/ro
# cleanup
umount /proc
umount /sys
# Boot the real thing
exec switch_root /aufs /sbin/init
else
# revert to normal rootfs
# remount root rw
mount -o remount,rw \${ROOTDEV}
# cleanup
umount /proc
umount /sys
# Boot the real thing
exec switch_root /rootfs /sbin/init
fi
echo "Failed to switch_root, dropping to a shell"
exec /bin/sh
EOF
# make init executable
chmod a+x init
# create the initramfs image
find . | cpio -H newc -o > ../initramfs.cpio
cp /proc/config.gz ~/config.gz
# uninstall busybox
sudo apt-get remove busybox-static e2fsck-static
Shutdown your RPI, and connect the sdcard to your DEVPC and mount the boot and root partitions
DEVPC:
# set variables
export BOOTDIR=/mnt/boot
export ROOTDIR=/mnt/root
# install necessary applications, download ARM toolchain, raspberry linux source and aufs
export BOOTDIR=/mnt/boot
export ROOTDIR=/mnt/root
# install necessary applications, download ARM toolchain, raspberry linux source and aufs
sudo apt-get install git-core build-essential bc -y
git clone git://github.com/raspberrypi/tools.git --depth=1 ~/raspberrypi/toolsgit clone -b rpi-3.12.y git://github.com/raspberrypi/linux.git --depth 1 ~/raspberrypi/src/linux
git clone -b aufs3.12.x git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git --depth 1 ~/raspberrypi/src/linux/aufs3-standalone
# set variable with crosscompiler toolchain prefix
echo export CCPREFIX=$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- >> ~/.bashrc
source ~/.bashrc
# integrate aufs in linux build tree
cd ~/raspberrypi/src/linux
cp -a aufs3-standalone/fs .
cp aufs3-standalone/include/uapi/linux/aufs_type.h include/uapi/linux/
patch -p1 < aufs3-standalone/aufs3-kbuild.patch
patch -p1 < aufs3-standalone/aufs3-base.patch
patch -p1 < aufs3-standalone/aufs3-mmap.patch
patch -p1 < aufs3-standalone/aufs3-standalone.patch
# clean build directory
make mrproper
# copy initramfs + kernelconfig
cp ${ROOTDIR}/home/pi/initramfs.cpio ${ROOTDIR}/home/pi/config.gz ~/raspberrypi/src/linux
zcat config.gz > .config
# set initramfs.cpio in kernel config
sed -i 's/.*CONFIG_BLK_DEV_INITRD.*/CONFIG_BLK_DEV_INITRD=y/g' .config
sed -i 's/.*CONFIG_INITRAMFS_SOURCE.*/CONFIG_INITRAMFS_SOURCE="initramfs.cpio"/g' .config
cat >> .config <<EOF
CONFIG_AUFS_FS=y
CONFIG_AUFS_BRANCH_MAX_127=y
# CONFIG_AUFS_BRANCH_MAX_511 is not set
# CONFIG_AUFS_BRANCH_MAX_1023 is not set
# CONFIG_AUFS_BRANCH_MAX_32767 is not set
CONFIG_AUFS_SBILIST=y
# CONFIG_AUFS_HNOTIFY is not set
# CONFIG_AUFS_EXPORT is not set
# CONFIG_AUFS_RDU is not set
# CONFIG_AUFS_SP_IATTR is not set
# CONFIG_AUFS_SHWH is not set
# CONFIG_AUFS_BR_RAMFS is not set
# CONFIG_AUFS_BR_FUSE is not set
# CONFIG_AUFS_BR_HFSPLUS is not set
CONFIG_AUFS_BDEV_LOOP=y
# CONFIG_AUFS_DEBUG is not set
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
EOF
# update kernel config, compile kernel and install modules
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j8 -k
make ARCH=arm modules_install INSTALL_MOD_PATH=../
#set kernel version
export KERNELVERSION=3.12.19+
#copy kernel to rootfs on sdcard
sudo cp arch/arm/boot/Image ${BOOTDIR}/kernel_aufs.img
# remove symbolic links from modules directory
rm ../lib/modules/${KERNELVERSION}/source
rm ../lib/modules/${KERNELVERSION}/build
# backup old modules
[ -d ${ROOTDIR}/lib/modules/${KERNELVERSION}.org ] || [ ! -d ${ROOTDIR}/lib/modules/${KERNELVERSION} ] || sudo mv ${ROOTDIR}/lib/modules/${KERNELVERSION} ${ROOTDIR}/lib/modules/${KERNELVERSION}.org
# copy new modules
sudo cp -a ../lib/modules/${KERNELVERSION} ${ROOTDIR}/lib/modules
# set new in kernel in config.txt
sudo sed -i 's/^kernel/#kernel/' ${BOOTDIR}/config.txt
sudo echo "kernel=kernel_aufs.img" >> ${BOOTDIR}/config.txt
# set tmpfs as rwfs in cmdline.txt
sudo sed -i 's/$/ rwfs=tmpfs/' ${BOOTDIR}/cmdline.txt
# comment out rootfs in fstab
sudo sed -i '/\/dev\/mmcblk0p2/s/^/#/g' /etc/fstab