Skip to content

Instantly share code, notes, and snippets.

@rikka0w0
Last active July 20, 2023 13:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rikka0w0/f56977f81d1228fc503b00ad7b526aa7 to your computer and use it in GitHub Desktop.
Save rikka0w0/f56977f81d1228fc503b00ad7b526aa7 to your computer and use it in GitHub Desktop.
SquashFS + JFFS2 root on LicheePi Nano

In order to save space on the SPI flash, SquashFS + JFFS2 should be used.

SPI Flash structure

Partition	Content		Offset		Size (byte)
mtd0		uboot-bin	0		0x58000 (360448)
		uboot-env	0x58000		0x8000
mtd1		dtb		0x60000		0x4000  (16kB)
mtd2		kernel		0x64000		0x400000 (4MB)
mtd3		rootfs		0x464000	0x4FC000 (4.98MB)
mtd4		overlay		0x960000	0x500000 (5MB)
  1. mtd0: Uboot image, contains the uboot binary and space for environmental variables. (u-boot-sunxi-with-spl.bin)
  2. mtd1: the device tree for Linux system. (arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb)
  3. mtd2: the kernel image for Linux system. (zImage)
  4. mtd3: compressed root image for the lower part of the overlay
  5. mtd4: a writable JFFS2 partition, for the upper part of the overlay In this example, the writable partition does not use up the entire flash, you can if you want. Note: the offset of mtd4 should be multiple of erase size (0x10000 for 25Q128 in this case), otherwise Linux won't be able to perform any write operation on it!

Uboot Options

No need to change any .c or .h files. Only need to go through menuconfig.

make ARCH=arm menuconfig
# Edit the followings
# [*] Enable boot arguments
   = console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=squashfs init=/etc/preinit
# [*] Enable a default value for bootcmd
   = sf probe 0 50000000; sf read 0x80C00000 0x60000 0x4000; sf read 0x80008000 0x64000 0x400000; bootz 0x80008000 - 0x80C00000
# Environment -> Environment Offset = 0x58000

u-boot-sunxi-with-spl.bin = Uboot itself + enviroment variables, a normal Uboot binary is ~270kB, so set 0x58000 bytes should be enough. The uboot partition size should be Environment Offset + Environment Size = 0x60000.

Linux Kernel

  1. Enable through menuconfig:
File systems:

<*> Overlay filesystem support
[*] Miscellaneous filesystems  --->
--><*>   Journalling Flash File System v2 (JFFS2) support
--><*>   SquashFS 4.0 - Squashed file system support

Device Drivers:
<*> Memory Technology Device (MTD) support  --->
--><*>   Caching block device access to MTD devices

[*] SPI support  --->
-->< >   Allwinner A10 SoCs SPI controller
--><*>   Allwinner A31 SPI controller
  1. Edit partition definition in the dts file
    flash: w25q128@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "winbond,w25q128", "jedec,spi-nor";
        reg = <0>;
        spi-max-frequency = <50000000>;
        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;

            partition@0 {
                label = "u-boot";
                reg = <0x000000 0x58000>;
                read-only;
            };

            partition@60000 {
                label = "dtb";
                reg = <0x60000 0x4000>;
                read-only;
            };

            partition@64000 {
                label = "kernel";
                reg = <0x64000 0x400000>;
                read-only;
            };

            partition@464000 {
                label = "rootfs";
                reg = <0x464000 0x4FC000>;
                read-only;
            };

            partition@960000 {
                label = "overlayfs";
                reg = <0x960000 0x500000>;
            };

        };
    };

  1. Build

RootFS (SquashFS)

  1. Extract a fresh rootfs:
mkdir rootfs_new
cd rootfs_new
tar xvpzf ../rootfs.tar.gz
  1. Create rootfs_new/etc/preinit and write:
#!/bin/sh

# export PATH="/usr/sbin:/usr/bin:/sbin:/bin"

# mount the new rootfs
mount -t squashfs /dev/mtdblock3 /rom
mount -t jffs2 /dev/mtdblock4 /overlay
mount -n -t overlay overlayfs:/overlay -o lowerdir=/rom,upperdir=/overlay/rw,workdir=/overlay/work /chroot

# mount /dev and /sys for chroot environment
# /dev/pts, /dev/shm, /proc, /tmp and /run will be mounted by inittab from fstab
mount -t sysfs sysfs /sys
mount --rbind /sys /chroot/sys/
mount --rbind /dev /chroot/dev/


exec chroot /chroot /sbin/init
  1. Create folders:
mkdir rootfs_new/overlay
mkdir rootfs_new/chroot
mkdir rootfs_new/rom
  1. Make the rootfs: mksquashfs rootfs_new/ rootfs_new.img -no-exports -no-xattrs -all-root

JFFS2 (Writable filesystem)

Empty in the example, but you can add other things.

mkdir -p overlay/work
mkdir -p overlay/rw
mkfs.jffs2 -s 0x100 -e 0x10000 --pad=0x500000 -o jffs2.img -d overlay/

Flash everything to SPI flash

# uboot
sudo sunxi-fel -p spiflash-write 0 u-boot/u-boot-sunxi-with-spl.bin
# dtb
sudo sunxi-fel -p spiflash-write 0x60000 linux/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
# kernel
sudo sunxi-fel -p spiflash-write 0x64000 linux/arch/arm/boot/zImage
# squashfs
sudo sunxi-fel -p spiflash-write 0x464000 rootfs_new.img
# jffs2
sudo sunxi-fel -p spiflash-write 0x960000 jffs2.img

See also

https://gist.github.com/rikka0w0/e04eee5fa623b37866ded805c855f287
https://whycan.cn/t_2179_2.html
https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt \

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment