Embedded systems should be resilient. I mean really resilient. They need to survive power cycles, accidental power loss, harsh environments and a lot of other unexpected stuff. In this regard SD card used by Raspberry Pi can be a little problematic. Especially since there are a lot of "useless" write operations that can be avoided, thus significantly prolonging memory card's life. Following on that, a read-only filesystem on Raspbian can be configured as there is already support for the Overlay Filesystem since the kernel version 3.18.8.
Let's get down to bussiness. I am working on Raspi 2, running the following kernel.
pi@raspberrypi:~$ uname -a Linux raspberrypi 4.1.13-v7+ #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015 armv7l GNU/Linux
Overlay Filesystem must be loaded at boot time, therefore we need to build Initial Ramdisk Filesystem (initramfs) image & enable it. Luckily support for this is also included in the kernel :-) First we add needed modules to the config.
# install initramfs tools if needed apt-get install initramfs-tools # Add the folowing lines at the bottom of /etc/initramfs-tools/modules # Use your preffered text editor # overlay filesystem overlay
Next, we need to add the bash script that will mount root filesystem as read-only to the initramfs. The script should also load overlays to the appropriate mount points and create directories if needed. Now, we could invent the square wheel here, but I have tested this script here and it works like a charm. Let's include it in the initramfs directory structure.
# let's say you downloaded from the link above to the home directory sudo cp root-ro.txt /etc/initramfs-tools/scripts/init-bottom/root-ro
Now we're ready to build initramfs image. The command below will create an image file in the /boot directory of your filesystem. The image will be built against the current running kernel version. The configured modules in the config file above must therefore be found in the current kernel module directory. In our case this is /lib/modules/4.1.13-v7+/kernel.
sudo mkinitramfs -o /boot/initrd.img-$(uname -r)
If you have come successfully so far, you're almost done. You might even take a break should you need one :-). Finally, we enable initramfs in the /boot/config.txt file. Just add at the bottom.
# initial ramdisk definition initramfs initrd.img-4.1.13-v7+
At the same time, we must also add driver parameter to the kernel command line. I would also suggest adding a debug parameter for the initramfs.
# this is my /boot/cmdline.txt file # debug parameter will create # /run/initramfs/initramfs.debug file dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait root-ro-driver=overlay debug
Now do a reboot and you should be done. After a login, you should see a screen similar to this. Note the read-only root filesystem and the overlay type filesystem with appropriate parameters lowerdir and upperdir.