User Tools

Site Tools


Read-only root for Raspberry Pi

Debian is a good choice to run on Raspberry Pi. To create a read-only rootfs for our Debian system we need to:

  • Compile a kernel with overlayfs support
  • Create an initramfs that will setup our read-only root
  • Create some helper scripts to remount root as read-write and to sync any changes back to the disk

With the help of overlayfs we can mount the disk read-only and run the rootfs from RAM. We can then pull the plug on the device without worrying of filesystem corruption. We can also mount the disk read-write to sync any changes back to the drive.

For this to work we are going to use a couple of directorys on the disk.

  • /mnt/root-ro, mountpoint of our disk
  • /mnt/root-rw, overlayfs mountpoint running in RAM (tmpfs)
  • /mnt/persistent, here we will store any changes to files and directories

Overlayfs will merge /mnt/root-ro with /mnt/root-rw into root (/).

Kernel compilation with overlayfs support

Complete instructions for kernel compilation can be found at

# Clone the raspberry kernel
# -b switch is used to select branch
cd /home/me/raspberry/kernel
git clone -b rpi-4.9.y --depth 1 ./
# Tell where we can find the kernel
# Get the raspberry toolchain
cd /home/me/raspberry/tools
git clone --depth 1 ./
# Tell where we can find the raspberry toolchain
# Let us build the kernel
# latest kernel already has support for overlayfs built in, the default is to build it as a module
ARCH=arm CROSS_COMPILE=${CCPREFIX} make bcm2709_defconfig
# Build our kernel
# Tell where we should put the kernel modules
# Copy our kernel modules to our module directory

Prepare initramfs

# Clone the raspberry busybox initramfs
cd /home/me/raspberry/initramfs
git clone --depth 1 ./

New init file.

cat > init << EOF
#!/bin/busybox sh
# Mount the /proc and /sys filesystems.
mount -t proc none /proc
mount -t sysfs none /sys
# Populate /dev
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# Do overlayfs magic
mount -o ro /dev/mmcblk0p2 /mnt/root-ro
mount -t tmpfs tmpfs /mnt/root-rw
cp -a /mnt/root-ro/mnt/persistent/. /mnt/root-rw
mount -t overlayfs overlayfs -o lowerdir=/mnt/root-ro,upperdir=/mnt/root-rw /rootfs
# Move mounts
mount --move /mnt/root-ro /rootfs/mnt/root-ro
mount --move /mnt/root-rw /rootfs/mnt/root-rw
# Clean up.
umount /proc
umount /sys
exec switch_root /rootfs /bin/systemd
# give init exec privileges
chmod +x init
mkdir -p mnt/root-ro
mkdir -p mnt/root-rw
mkdir rootfs
mkdir proc
mkdir sys
mkdir dev
# you might also want to disable some mdev rules
echo > etc/mdev.conf

When we're finished modifying our initramfs we create it by running:

cd /home/me/raspberry/initramfs
# skip .git dir by find
find . -name .git -a -type d -prune -o -print | cpio -o -H newc > ../initramfs.cpio
cd ..
gzip -c initramfs.cpio > initramfs.img

Create rootfs with debootstrap

I wrote a little script that will deboostrap a minimal raspberry rootfs. Run as ./ [directory to debootstrap to]. Download at

mkdir /home/me/raspberry/rootfs
./ /home/me/raspberry/rootfs
cd /home/me/raspberry/rootfs
mkdir -p mnt/root-ro
mkdir -p mnt/root-rw
mkdir -p mnt/persistent

Helper scripts for rootfs

cat > /bin/remountro << EOF
echo -e "Remounting rootfs as read-only..."
mount -o remount,ro /mnt/root-ro
echo "DONE."
cat > /bin/remountrw << EOF
echo -e "Remounting rootfs as read-write..."
mount -o remount,rw /mnt/root-ro
echo "DONE."
cat > /bin/syncroot << EOF
echo -e "Syncing rootfs...\n"
rsync -a -H -A -X --delete /mnt/root-rw/. /mnt/root-ro/mnt/persistent
echo "DONE."
chmod +x /bin/remountro
chmod +x /bin/remountrw
chmod +x /bin/syncroot
linux/raspberry_pi_read-only_root.txt · Last modified: 2017/11/29 18:51 by kacper