Flash layout
The image uses all 16 MiB of NOR flash with no gaps between regions. The first 8 KiB is the mandatory ROM FlashEncryption reservation; every remaining byte belongs to one of the slots below. Range ends are exclusive.
Raw start |
Raw end |
Capacity |
Contents |
|---|---|---|---|
|
|
8 KiB |
Reserved for ROM FlashEncryption metadata |
|
|
48 KiB |
|
|
|
320 KiB |
|
|
|
64 KiB |
|
|
|
1536 KiB |
|
|
|
2120 KiB |
Persistent JFFS2 filesystem |
|
|
6144 KiB |
|
|
|
6144 KiB |
|
Persist fills the space between radio and Linux. There is no separate HIL
scratch partition. The seven child MTD partitions are read-only except persist.
CONFIG_MTD_PARTITIONED_MASTER=y intentionally also exposes the writable
40000000.flash master device covering all 16 MiB. Master access bypasses the
child partitions’ read-only flags and includes the reserved prefix and boot
slots; callers must account for those ranges when performing raw operations.
Persist/rootfs are found by label, not by fixed MTD device numbers.
The same whole-flash master is continuously readable from offset 0 through
0xFFFFFF. Linux supplies its normal /dev/mtdN character node and a
read-only /dev/mtdNro alias; identify N from the sysfs name
40000000.flash rather than assuming its number. Reading the read-only alias
covers the complete 16 MiB, including the reserved prefix and every partition,
without granting write access through that alias. With CONFIG_MTD_BLOCK=y,
/dev/mtdblockN also exposes the complete master as a block device. The writable
master is intentionally retained by the full-board configuration.
Raw offsets and XIP addresses
The boot mapping covers raw flash [0x000000, 0x1000000) linearly at physical
[0x40000000, 0x41000000). Therefore the FIT is at 0x4000E000, OpenSBI’s
XIP payload starts at 0x4000E400, the Linux DTB is at 0x4005E000, and Linux
starts at 0x40400000.
The Linux start is aligned to a 4 MiB Sv32 megapage. This matters for kernels
larger than 4 MiB: an unaligned XIP start can reach the page-table BUG_ON
described in issue #1.
Do not move Linux merely to close a gap; persist already fills the space up
to the required boundary.
The radio slot starts at physical 0x4006E000 and virtual 0xBE06E000, inside
the aligned 4 MiB leaf mapping from virtual 0xBE000000 to physical
0x40000000. See Memory map and
Boot process.
Change the layout
The offsets and filenames are defined in
configs/esp32s31-layout.cfg.
The merge script checks that each file fits its region, including the 48 KiB
SPL limit. Coordinate changes with the bootloader, OpenSBI, kernel XIP and
radio mappings, device-tree partitions, image tooling, and flashing commands.
Run python3 tools/checks/layout.py from the parent repository to check the
shared flash and SRAM contracts. To read a slot capacity in bytes, use, for
example, python3 tools/checks/layout.py --size PERSIST.
The radio XIP image is linked against the kernel and must be updated with its
matching kernel/module. The Linux radio module lives in rootfs.sqfs.
Preserve data
Slot-wise make flash-existing-all (flash-all is an alias) leaves persist untouched only when the board
already uses this layout. Writing the contiguous s31_full_flash.bin
overwrites persist, even without a separate chip erase.
Whenever changing the installed layout, back up needed files and settings to another device, verify the backup, perform a clean installation, then restore the needed files/settings. See Flash and first boot.