Quest for software verification Since more than a week now, I'm after a task which was originally estimated to take a few days. An experienced colleague pushed to migrate the boot procedure from a reasonable setup based on FIT[1] to an arrangement where the kernel and the device tree is loaded from the root filesystem. The reason behind this migration has to do with the convenience of implementing the cryptographic verification of the software in one step: only the root filesystem is verified, and this implies the verification of kernel and device tree in it contained. The system I'm trying to modify is using SquashFS for the root filesystem. SquashFS is supported by U-Boot, so it should have been as simple as requesting the loading of a certain filesystem path (e.g. "/boot/vmlinuz") to a designated memory area, and boot from there. As it turns out, the SquashFS support of U-Boot is unfortunately quite limited. It requires SquashFS to be constructed on the top of the UBI[2] support. I was suggested to fall back on using JFFS2, which should be supported in read-only mode from U-Boot. The unfortunate side effect is that our root filesystem will no longer be inherently read-only (SquashFS is read-only by design, JFFS2 can be mounted read-write under Linux), and of course that we should migrate the new (old) filesystem. Ironically, the easy part was figuring out how to do so with Yocto! The IMAGE_FSTYPES[3] setting allows to list what formats the build system should use for the root filesystem. I copied the image on the designated flash partition, and tried to load it from U-Boot. It took me a while to find out about 'mtdids'+'mtdparts'[4], what should be the correct values for them, and what build-time configurations to enable in order to get the desired code activated. All those build-time conditionals, and the practice of silently skipping disabled code, can make U-Boot very difficult to work with. I reached the point where the values of 'mtdids' and 'mtdparts' determined a promising long delay between the 'fsls' command and a remarkably empty list of files. Actually nothing really prevents those pesky 'mtdids' and 'mtdparts' variables to be still wrong. I tried to verify if the filesystem is usable, first by successfully mounting it on my Linux workstation, and then by mounting it, still on Linux but on the target board. The second step was not trivial but eventually successful. It was not trivial because the flash erase block matters on JFFS2, and the kernel has a configuration called CONFIG_MTD_SPI_NOR_USE_4K_SECTORS, active by default, which will force our flash to use 4 KiB erase blocks. Such configuration does not work well with our NOR flash. I finally managed to mount the new root filesystem under Linux (on target) by disabled such configuration, and configured Yocto to use 64KiB erase blocks for the image (the right knob for the purpose is JFFS2_ERASEBLOCK[5]). A build-time configuration with the same name, meaning, and default value also exists under U-Boot, so I had to disable it consistently. Despite my efforts, I still can not access the filesystem from U-Boot! I can boot the kernel with the JFFS2 image as root filesystem, which means that the problem is not in the image, nor in the kernel. I can also correctly load the filesystem in memory from U-Boot (acting on the 'sf' commands, which result in a memory transfer via the SPI bus to the main memory). I know the image is correct because I can dump the loaded bytes with the 'md' command, and it checks out. The thing is, unfortunately, that the JFFS2 driver will expect the data to be available from a memory mapped flash, and I'm not sure if the flash can even be accessed this way. I will now delve into the data-sheet of our target ASIC. Even if this battle is not yet over, it feels good to annotate the progress made so far. I'm no longer sure that this was a good idea, but at least I've gained some precious know-how. :) Additional reads: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface https://www.embedded.com/flash-101-the-nor-flash-electrical-interface/ References [1] Flattened Image Trees https://www.elinux.org/Fit-boot [2] Unsorted Block Images https://en.wikipedia.org/wiki/UBIFS#UBI [3] IMAGE_FSTYPES https://docs.yoctoproject.org/ref-manual/variables.html#term-IMAGE_FSTYPES [4] mtdparts https://github.com/u-boot/u-boot/blob/9e804638bfe2693a908abf066ff66c251572afa7/cmd/mtdparts.c#L26 [5] JFFS2_ERASEBLOCK https://docs.yoctoproject.org/ref-manual/variables.html#term-IMAGE_FSTYPES