Flash Management and JFFS2 File System Print

 

Linux provides management of the internal STM32F7 Flash and the on-board NOR Flash, including the ability to partition the physical Flash onto separate logical partitions and mount a JFFS2 Flash filesystem on a Flash partition.

The Flash management and JFFS2 filesystem require enabling appropriate kernel options in the kernel configuration and adding certain device nodes and Linux tools to the target file system. The rootfs project included in the Emcraft distribution at projects/rootfs provides a sample Linux configuration that has the Flash management and JFFS2 functionality fully enabled. The examples in the text below make use of the rootfs project.

Linux splits the external Flash onto several partitions. Even though the partitioning is purely logical in the software, the user view is that each Flash partition can be accessed as a separate "Flash disk" device, independent of the other Flash partitions. Each Flash partitioned can be accessed as a "raw" disk or, alternatively, a Flash file system can be mounted on a partition.

The Flash partitioning for internal STM32F7 Flash and NOR Flash are defined in project/rootfs/rootfs.dts.STM32F769IDISCO:

stm_flash {
status = "okay";
geometry = "stm32f76x.2M";
reg = <0x08000000 0x00200000>;

stm_flash_uboot@0 {
label = "stm_flash_uboot";
reg = <0x000000 0x020000>;
};

stm_flash_uboot_env@1 {
label = "stm_flash_uboot_env";
reg = <0x020000 0x020000>;
};

stm_flash_unused@1 {
label = "stm_flash_unused";
reg = <0x040000 0x1c0000>;
};
};
...
&qspi {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi>;
freq = <108000000>;
flash = "mt25ql512abb";

partition@0x0 {
label = "stm_qspi_linux_image";
reg = <0x00000 0xa00000>;
};
partition@0x1 {
label = "stm_qspi_fs";
reg = <0xa00000 0x3600000>;
};
};

The Flash layout included in the distribution provides a reasonable Flash partitioning for the on-board NOR Flash device, however, depending on your application needs, you might want to change the number and size of configured Flash partitions. We don't recommend to change the layout of the STM32F7 internal Flash.

When Linux boots on the target, there will be the following messages in the kernel print-out indicating that the Flash driver is enabled and then describing the specific partitions created by the kernel:

3 ofpart partitions found on MTD device physmap-stm-flash.0
Creating 3 MTD partitions on "physmap-stm-flash.0":
0x000000000000-0x000000020000 : "stm_flash_uboot"
0x000000020000-0x000000040000 : "stm_flash_uboot_env"
0x000000040000-0x000000200000 : "stm_flash_unused"
stm32-pinctrl pin-controller: maps: function qspi group qspi num 7
stm32-quadspi a0001000.qspi: QSPI:  64 MB mapped at 90000000
2 ofpart partitions found on MTD device stm32-quadspi
Creating 2 MTD partitions on "stm32-quadspi":
0x000000000000-0x000000a00000 : "stm_qspi_linux_image"
0x000000a00000-0x000004000000 : "stm_qspi_fs"

In the above example, the first partition is used to hold the U-Boot image. The second partition is allocated to the U-Boot environment variables. The fifth partition is dedicated to the JFFS2 file system.

Let's start with creating a JFFS2 file system on the fifth partition. The following command erases the Flash partition and marks it up as a JFFS2 file system. JFFS2 provides transparent management of bad blocks and Flash wearing capabilities ensuring the robustness and longevity of the file system in Flash. Notice use of the -j flag as the indication to flash_eraseall that the partition must not only be erased but also marked up for JFFS2:

/ # flash_eraseall -j /dev/mtd4
Erasing 128 Kibyte @ 5e0000 - 100% complete.Cleanmarker written at 5c0000.
/ #

Now everything is ready to mount a JFFS2 file system on that partition. As expected, the initial file system is empty:

/ # mkdir /m
/ # mount -t jffs2 /dev/mtdblock4 /m
/ # ls -lt /m
/ #

Let's add some files to the JFFS2 file system and validate that they are correct. In the example below, we copy the busybox binary from the initramfs root file system to Flash and then run it from Flash:

/ # cp /bin/busybox /m
/ # /m/busybox echo Hello from JFFFS2
Hello from JFFFS2
/ #

Now, let's reboot the system and make sure that any updates we make in the JFFS2 are indeed persistent:

/ # reboot -f
Restarting system
...
Linux version 4.2.0-cortexm-2.3.2 (psl@skywanderer.emcraft.com) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #2 Mon Mar 10 11:19:44 +0400 2017
...
init started: BusyBox v1.17.0 (2016-09-19 11:07:14 +0400)
/ # mkdir /m
/ # mount -t jffs2 /dev/mtdblock4 /m
/ # /m/busybox echo Hello from JFFS2 after reboot
Hello from JFFS2 after reboot
/ #

As a next step, let's update the Linux uImage in the forth partition from a host directory mounted over NFS. This provides a simple demonstration of a possible software upgrade sequence using a Linux image pulled from the network.

First step is to prepare the partition for a new uImage by erasing the Flash:

/ # flash_eraseall /dev/mtd4
Erasing 128 Kibyte @ a00000 - 100% complete.
/ #

Let's mount the host directory over NFS and copy a prebuilt uImage to Flash. In this example, we install the Linux image for the rebuilt rootfs project:

/ # mount -o nolock 192.168.1.102:/mnt/work/emcraft/bsp/nfs /mnt
/ # flashcp -v /mnt/rootfs.uImage /dev/mtd4
Erasing block: 45/45 (100%)
Writing kb: 5632/5638 (99%)
Verifying kb: 5632/5638 (99%)
/ #

Now, we are ready to reboot and validate the target is indeed running the newly installed Linux project:

/ # reboot -f
reboot: Restarting system

U-Boot 2010.03-cortexm-2.3.2 (Mar 10 2017 - 11:18:48)

CPU : STM32F7 (Cortex-M7)
Freqs: SYSCLK=216MHz,HCLK=216MHz,PCLK1=54MHz,PCLK2=108MHz
Board: STM32F769I-DISCO Revision B-01, www.emcraft.com
DRAM: 16 MB
In: serial
Out: serial
Err: serial
QSPI:  64 MB mapped at 0x90000000
Net: STM32_MAC
Hit any key to stop autoboot: 0
## Booting kernel from Legacy Image at 90000000 ...
Image Name: Linux-4.2.0-g4095f1f-dirty
Image Type: ARM Linux Multi-File Image (uncompressed)
Data Size: 5774071 Bytes = 5.5 MB
Load Address: c0008000
Entry Point: c0008001
Contents:
Image 0: 5756576 Bytes = 5.5 MB
Image 1: 17483 Bytes = 17.1 kB
Verifying Checksum ... OK
## Flattened Device Tree from multi component Image at 90000000
Booting using the fdt at 0x6059d6ec
Loading Multi-File Image ... OK
OK
Loading Device Tree to c1ff8000, end c1fff44a ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.2.0-g4095f1f-dirty (void@ubuntu) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #3 Mon Mar 19 21:14:07 +0400 2017
CPU: ARMv7-M [410fc271] revision 1 (ARMv7M), cr=00000000
...
init started: BusyBox v1.24.2 (2017-03-19 17:17:05 +0400)
/ #