Using SquashFS As A Read-Only Root File System

This guide describes the usage of SquashFS. SquashFS (http://goo.gl/WT6Lxf) is a compressed read-only file system for Linux on ODROID-XU4 based system series like the HC1, HC2, MC1 and XU3. RootFS (http://goo.gl/LMVjzS) corruption rate after power failures will be significantly reduced because SquashFS is a very robust file system. Note that a properly working built-in SquashFS is available in Kernel 4.14.5-92 or higher.

Preparation
You need to prepare a bootable microSD card or eMMC module with an Ubuntu minimal image. For instructions on how to write images to a card, refer to the flashing-tools Wiki at http://goo.gl/FNRzAk. This guide assumes use of a microSD card.

Installation
You can install the squashfs-tools on your ODROID-XU4 system. It is the tool for creating squashed file systems.

$ sudo apt install squashfs-tools

Creating squashed root file system image
The following steps are required to create the squashed root file system image:

  • Removal of the auto-resize script
  • Editing /etc/rc.local and removing auto-resize feature
  • Editing /etc/fstab and removing the root mount option
  • Using mksquashfs for creating read-only root file systems

$ sudo rm /media/ck/rootfs/aafirstboot
 $ sudo cat /media/ck/rootfs/etc/rc.local
 #!/bin/sh -e
 #
 # rc.local
 #
 # This script is executed at the end of each multiuser runlevel.
 # Make sure that the script will "" on success or any other
 # value on error.
 #
 # In order to enable or disable this script just change the execution
 # bits.
 #
 # By default this script does nothing.

if [ -f /aafirstboot ]; then /aafirstboot start ; fi

exit 0

$ sudo nano /media/ck/rootfs/etc/rc.local
 $ sudo cat /media/ck/rootfs/etc/rc.local
 #!/bin/sh -e
 #
 # rc.local
 #
 # This script is executed at the end of each multiuser runlevel.
 # Make sure that the script will "" on success or any other
 # value on error.
 #
 # In order to enable or disable this script just change the execution
 # bits.
 #
 # By default this script does nothing.

exit 0
 $ sudo cat /media/ck/rootfs/etc/fstab
 UUID=e139ce78-9841-40fe-8823-96a304a09859 / ext4 errors=remount-ro,noatime 0 1
 LABEL=boot /media/boot vfat defaults 0 1

$ sudo nano /media/ck/rootfs/etc/fstab
 $ sudo cat /media/ck/rootfs/etc/fstab
 LABEL=boot /media/boot vfat defaults 0 1

$ sudo mksquashfs /media/ck/rootfs/ squash.rootfs
 Parallel mksquashfs: Using 8 processors
 Creating 4.0 filesystem on squash.rootfs, block size 131072.
 [================================================-] 36821/36821 100%
 Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
 compressed data, compressed metadata, compressed fragments, compressed xattrs
 duplicates are removed
 Filesystem size 423720.81 Kbytes (413.79 Mbytes)
 42.27% of uncompressed filesystem size (1002435.26 Kbytes)
 Inode table size 464688 bytes (453.80 Kbytes)
 28.95% of uncompressed inode table size (1604883 bytes)
 Directory table size 433806 bytes (423.64 Kbytes)
 39.67% of uncompressed directory table size (1093654 bytes)
 Xattr table size 48 bytes (0.05 Kbytes)
 40.00% of uncompressed xattr table size (120 bytes)
 Number of duplicate files found 2340
 Number of inodes 45340
 Number of files 31162
 Number of fragments 1912
 Number of symbolic links 10373
 Number of device nodes 79
 Number of fifo nodes 0
 Number of socket nodes 0
 Number of directories 3726
 Number of ids (unique uids + gids) 22
 Number of uids 6
 root (0)
 man (6)
 dnsmasq (104)
 rtkit (107)
 libuuid (100)
 avahi-autoipd (105)
 Number of gids 18
 root (0)
 video (44)
 audio (29)
 tty (5)
 kmem (15)
 disk (6)
 dip (30)
 shadow (42)
 utmp (43)
 messagebus (106)
 ssh (111)
 mlocate (110)
 staff (50)
 avahi-autoipd (113)
 netdev (102)
 adm (4)
 scanner (109)
 mail (8)

Squashed file systems on microSD card
If everything went fine, unmount /dev/sdc2 (if needed) and use dd to copy squash.rootfs to /dev/sdc2:

  • Unmount all microSD partitions
  • Use dd to copy squash.rootfs file to microSD partition #2
  • Reconnect the microSD card and check the mount

$ mount
 /dev/sdc2 on /media/ck/rootfs type ext4 (rw,nosuid,nodev,uhelper=udisks2)
 /dev/sdc1 on /media/ck/boot type vfat (rw,nosuid,nodev,uid=1000,gid=1000,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks2)
 $ sudo umount /dev/sdc?
 $ sudo dd if=./squash.rootfs of=/dev/sdc2
 $ sync
 $ mount

/dev/sdc2 on /media/ck/disk type squashfs (ro,nosuid,nodev,uhelper=udisks2)
 /dev/sdc1 on /media/ck/boot type vfat (rw,nosuid,nodev,uid=1000,gid=1000,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks2)

Modifying rootfs mount options in the boot.ini file
You can find the UUID of the ext4 partition in the “root=” option in the boot.ini file:

/media/ck/boot/boot.ini

 #------------------------------------------------------------------------------------------------------
 # Basic Ubuntu Setup. Don't touch unless you know what you are doing.
 # --------------------------------
 setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro fsck.repair=yes net.ifnames=0"
 Find the bootrootfs environment and change the rootfs options as follows:
 This HOWTO using a microSD card. If you are using an eMMC module, you can use root=mmcblk0p2
 #------------------------------------------------------------------------------------------------------
 # Basic Ubuntu Setup. Don't touch unless you know what you are doing.
 # --------------------------------
 setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=/dev/mmcblk1p2 rootfstype=squashfs rootwait ro net.ifnames=0"
 $ nano /media/ck/boot/boot.ini
 $ cat /media/ckkim/boot/boot.ini | grep bootrootfs
 setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=/dev/mmcblk1p2 rootfstype=squashfs rootwait ro net.ifnames=0"
 setenv bootargs "${bootrootfs} ${videoconfig} ${hdmi_phy_control} ${hid_quirks} smsc95xx.macaddr=${macaddr} ${external_watchdog} governor=${governor}"

Now just ensure that everything works fine. Do not forget to set the boot mode switch to microSD card. The odroid login is “root” with a password of “odroid”.
# mount
 sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
 proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
 udev on /dev type devtmpfs (rw,nosuid,relatime,size=952168k,nr_inodes=186804,mode=755)
 devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
 tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=204240k,mode=755)
 /dev/mmcblk1p2 on / type squashfs (ro,relatime)
 securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
 tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
 tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
 tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
 cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
 cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
 cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
 cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
 cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
 cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
 cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
 cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
 cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
 cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
 systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=27,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
 mqueue on /dev/mqueue type mqueue (rw,relatime)
 debugfs on /sys/kernel/debug type debugfs (rw,relatime)
 configfs on /sys/kernel/config type configfs (rw,relatime)
 /dev/mmcblk1p1 on /media/boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
 tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=204240k,mode=700)

Example: Make the /home writable.

  • Create a new ext4 partition on the microSD card
  • Unpack squashfs-root
  • Make new /media/data directory
  • Edit /etc/fstab to mount ext4 data partition rw
  • Add/modify as per your taste then recreate squash.rootfs
  • Copy the newly created squash.rootfs over the existing one on microSD card
  • Boot using microSD card with new image

$ sudo umount /dev/sdc?
$ sudo fdisk /dev/sdc
$ sudo mkfs.ext4 /dev/sdc3 -L data
$ sudo unsquashfs squash.rootfs
$ sudo mkdir -p squashfs-root/media/data
$ sudo nano squashfs-root/etc/fstab
$ cat squashfs-root/etc/fstab
 LABEL=boot /media/boot vfat defaults 0 1
 LABEL=data /media/data ext4 defaults 0 1
$ sudo mksquashfs squashfs-root/ squash.rootfs.1
$ sudo dd if=./squash.rootfs.1 of=/dev/sdc2

Reboot and use the microSD card containing the new image.
# mount | grep mmc
 /dev/mmcblk1p2 on / type squashfs (ro,relatime)
 /dev/mmcblk1p1 on /media/boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
 /dev/mmcblk1p3 on /media/data type ext4 (rw,relatime,data=ordered)

For example, the overlayfs (http://goo.gl/1UGThG) enabled as a module in the 4.14.y kernel can be used. Use overlayfs to make /home writable.
# modprobe overlay
 # lsmod
 Module Size Used by
 overlay 65536 0
 joydev 20480 0
 spidev 20480 0
 spi_s3c64xx 20480 0
 exynos_gpiomem 16384 0
 ipv6 380928 28
 # mkdir -p /media/data/home
 # mkdir -p /media/data/home/upper
 # mkdir -p /media/data/home/work
 # mount -t overlay -o lowerdir=/home,upperdir=/media/data/home/upper,workdir=/media/data/home/work overlay /home
 # mount
 ...
 overlay on /home type overlay (rw,relatime,lowerdir=/home,upperdir=/media/data/home/upper,workdir=/media/data/home/work)
 # cd /home
 # touch file1
 # ls
 file1

For comments, questions and suggestions, please visit the SquashFS Wiki article at http://goo.gl/Xw2epe.

Be the first to comment

Leave a Reply