SquashFS is a very popular read-only compressed root filesystem, widely used in embedded systems. It has been supported in the Linux kernel for many years, but so far the U-Boot bootloader did not have support for SquashFS, so it was not possible to load a kernel image or a Device Tree Blob from a SquashFS filesystem in U-Boot.
Between February 2020 and August 2020, João Marcos Costa from the ENSICAEN engineering school, has worked at Bootlin as an intern. João’s internship goal was specifically to implement and contribute to U-Boot the support for the SquashFS filesystem. We are happy to announce that João’s effort has now completed, as the support for SquashFS is now in upstream U-Boot. It can be found in fs/squashfs/ in the U-Boot source code.
More specifically, João’s contributions have been:
- fs/squashfs: new filesystem, this is the core of the contribution, the SquashFS filesystem driver itself
- fs/squashfs: add filesystem commands, which adds the
sqfsloadcommands in U-Boot
- include/u-boot, lib/zlib: add sources for zlib decompression and fs/squashfs: add support for zlib decompression, which add support for zlib decompression in the SquashFS driver
- test/py: Add tests for the SquashFS commands, which extends the U-Boot test suite to also test the SquashFS fielsystem support
In addition to those contributions already merged, João has also submitted for inclusion the support for LZO and ZSTD decompression support.
Practically speaking, this SquashFS support works very much like the support for other filesystems. At build time, you need to enable the
CONFIG_FS_SQUASHFS option for the SquashFS driver itself, and
CONFIG_CMD_SQUASHFS for the SquashFS U-Boot commands. Once enabled, in U-Boot, you get:
=> sqfsls sqfsls - List files in directory. Default: root (/). Usage: sqfsls
[ ] [directory] - list files from 'dev' on 'interface' in 'directory' => sqfsload sqfsload - load binary file from a SquashFS filesystem Usage: sqfsload [ [ [ [bytes [pos]]]]] - Load binary file 'filename' from 'dev' on 'interface' to address 'addr' from SquashFS filesystem. 'pos' gives the file position to start loading from. If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'. 'bytes' gives the size to load. If 'bytes' is 0 or omitted, the load stops on end of file. If either 'pos' or 'bytes' are not aligned to ARCH_DMA_MINALIGN then a misaligned buffer warning will be printed and performance will suffer for the load.
sqfsls is obviously used to list files, here the list of files from a typical Linux root filesystem:
=> sqfsls mmc 0:1 bin/ boot/ dev/ etc/ lib/ <SYM> lib32 <SYM> linuxrc media/ mnt/ opt/ proc/ root/ run/ sbin/ sys/ tmp/ usr/ var/ 2 file(s), 16 dir(s)
And then you can use
sqfsload to load files, which we illustrate here by loading a Linux kernel image and Device Tree blob, and booting this kernel:
=> sqfsload mmc 0:1 $kernel_addr_r /boot/zImage 6160384 bytes read in 433 ms (13.6 MiB/s) => sqfsload mmc 0:1 0x81000000 /boot/am335x-boneblack.dtb 40817 bytes read in 11 ms (3.5 MiB/s) => setenv bootargs console=ttyO0,115200n8 => bootz $kernel_addr_r - 0x81000000 ## Flattened Device Tree blob at 81000000 Booting using the fdt blob at 0x81000000 Loading Device Tree to 8fff3000, end 8fffff70 ... OK Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.19.79 (joaomcosta@joaomcosta-Latitude-E7470) (gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05)) #1 SMP Fri May 29 18:26:39 CEST 2020 [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
Of course, the SquashFS driver is still fresh, and there is a chance that more extensive and widespread testing will uncover a few bugs or limitations, which we’re sure the broader U-Boot community will help address. Overall, we’re really happy to have contributed this new functionality to U-Boot, it will be useful for our projects, and we hope it will be useful to many others in the embedded Linux community!