The big advantage with aufs over unionfs is the ability to update the read-only filesystem while the system is running. There is no need to boot the system to a single user or use an external methods to sync the filesystems.
Requisites
- - a working cross compiler or native build environment (this is very slow)
- an extra partition to hold the read-write filesystem
- a working Raspbian setup
- (1) create the initramfs cpio image on the RPI:(2) transfer the resulting initramfs.cpio and /proc/config.gz to the development machine
Code: Select all
# temporarily install busysbox and e2fsck sudo apt-get 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 mknod -m 622 dev/console c 5 1 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 # create init file 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 # uninstall busybox sudo apt-get remove busybox-static e2fsck-static
(3) download the RPi kernel and the aufs sources(4) extract the kernel config file and copy the initramfs imageCode: Select all
cd <working dir> # download linux source git clone -b rpi-3.2.27 --depth 1 git://github.com/raspberrypi/linux.git cd linux # download aufs source git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git cd aufs3-standalone git checkout origin/aufs3.2 # copy aufs source to linux tree cp -a fs ../ cp include/linux/aufs_type.h ../include/linux/ cd .. # apply patches patch -p1 < aufs3-standalone/aufs3-kbuild.patch patch -p1 < aufs3-standalone/aufs3-base.patch patch -p1 < aufs3-standalone/aufs3-proc_map.patch patch -p1 < aufs3-standalone/aufs3-standalone.patch # make sure build directory is clean make mrproper(5) configure the kernelCode: Select all
export SRC="<source directory>" zcat ${SRC}/config.gz > .config cp ${SRC}/initramfs.cpio .use the defaults when asked except for the following entries:Code: Select all
# enable initramfs sed -i 's/# CONFIG_BLK_DEV_INITRD is not set/CONFIG_BLK_DEV_INITRD=y/' .config make ARCH=arm CROSS_COMPILE=arm-bcm2708hardfp-linux-gnueabi- oldconfig(6) compile and install the modulesCode: Select all
Initramfs source file(s) (INITRAMFS_SOURCE) [] (NEW) initramfs.cpio Aufs (Advanced multi layered unification filesystem) support (AUFS_FS) [N/m/y/?] (NEW) y Hfsplus as an aufs branch (AUFS_BR_HFSPLUS) [Y/n/?] (NEW) n(7) transfer the kernel image and the modules to the RPi sd cardCode: Select all
make ARCH=arm CROSS_COMPILE=arm-bcm2708hardfp-linux-gnueabi- -j3 -k make ARCH=arm modules_install INSTALL_MOD_PATH=../(8) test using tmpfs as rw overlayCode: Select all
export BOOTDIR="<sd card boot dir>" export ROOTDIR="<sd card root dir>" # copy kernel image cp arch/arm/boot/Image ${BOOTDIR}/kernel_aufs.img # backup old modules [ -d ${ROOTDIR}/lib/modules/3.2.27+.org ] || [ ! -d ${ROOTDIR}/lib/modules/3.2.27+ ] || mv ${ROOTDIR}/lib/modules/3.2.27+ ${ROOTDIR}/lib/modules/3.2.27+.org # copy new modules cp -a ../lib/modules/3.2.27+ ${ROOTDIR}/lib/modules(9) boot RPi, you should see the following entries when you run the mount command:Code: Select all
# use the new image sed -i 's/^kernel/#kernel/' ${BOOTDIR}/config.txt echo "kernel=kernel_aufs.img" >> ${BOOTDIR}/config.txt # update cmdline sed -i 's/$/ rwfs=tmpfs/' ${BOOTDIR}/cmdline.txtCode: Select all
/dev/mmcblk0p2 on /ro type ext4 (ro,noatime,user_xattr,barrier=1,data=ordered) aufs-tmpfs on /rw type tmpfs (rw,relatime) aufs on / type aufs (rw,relatime,si=436b232b)
- kernel: http://dl.dropbox.com/u/17024524/kernel_aufs.img
modules: http://dl.dropbox.com/u/17024524/modules.tgz
- Here is my working setup. Note that both the rootfs and rw overlay must not be present in /etc/fstab. The /tmp and /var/log directories are mounted on tmpfs.
/etc/fstab/boot/config.txtCode: Select all
# <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat ro,defaults 0 0 tmpfs /tmp tmpfs nodev,nosuid,size=30M,mode=1777 0 0 tmpfs /var/log tmpfs nodev,nosuid,size=30M,mode=1777 0 0/boot/cmdline.txtCode: Select all
gpu_mem=16 kernel=kernel_aufs.imgpartition tableCode: Select all
smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait rwfs=/dev/mmcblk0p3 rwfstype=ext4Code: Select all
sfdisk -d # partition table of /dev/mmcblk0 unit: sectors /dev/mmcblk0p1 : start= 2048, size= 204800, Id= c /dev/mmcblk0p2 : start= 206848, size= 1953000, Id=83 /dev/mmcblk0p3 : start= 2159848, size= 1788696, Id=83 /dev/mmcblk0p4 : start= 0, size= 0, Id= 0
- - Root union filesystem on raspian
- aufs Root File System On Usb Flash
- HowTo rebuild Kernel for Raspberri-Pi to add aufs support
- RPi Kernel Compilation
Changelog:
03 Aug 2013 - Fixed segmentation fault in init script, always fsck the ROOT partition