
In a nit-picking moment trying to save some flash storage, I looked at the current typical flash layout of U-Boot and came up with below RFC.
Before I start to implement anything, I'd like to hear your comments about this, especially from the architecture maintainers. Given that you have some spare time to look into this, of course. Sorry in case this was discussed before, did only a coarse list archive search.
I'd volunteer to provide an implementation for the architectures I have close at hand today (Blackfin, ARM11), as time permits. For other architectures, I'd need some assistance.
Abstract --------
Approach to utilize flashes with different block sizes to reduce U-Boot flash footprint. In general only relevant for boards with environment in flash.
Prerequisites -------------
Quite a few NOR flashes are divided into different block sizes. For example, the widespread Intel/Numonyx/Micron P30 series is divided into 4 blocks of 32 kByte, followed by n blocks of 128 kByte. Depending on variant, the smaller blocks are the first blocks (bottom) or the last blocks (top). The bottom variant is more common, as it allows flexible total sizes without a change in the location of the small blocks.
Given a not uncommon U-Boot size of around 128kB (+/- a few 10kB), accompanied by a separate flash block for a configurable environment, it would make sense to make use of this layout.
All below statements are focused on NOR flashes like above, with environment in flash. Also things like standalone applications, out-of-binary graphics data, etc. are not taken into account. Hence this RFC, as I probably miss some requirements and/or problems.
Flash layouts -------------
Current best-case layout: 32kB U-Boot 32kB U-Boot 32kB U-Boot 32kB U-Boot 128kB U-Boot environment => 256kB flash used
Current worst-case layout: 32kB U-Boot 32kB U-Boot 32kB U-Boot 32kB U-Boot 128kB U-Boot (given U-Boot is >128kB) 128kB U-Boot environment 128kB optional: VPD => 384kB to 512kB flash used
Suggested layout: 32kB U-Boot environment 32kB U-Boot or optional VPD 32kB U-Boot 32kB U-Boot 128kB U-Boot => 256kB flash used with 192kB/224kB room for U-Boot
VPD: Vital Product Data (board type, MAC addresses, serial number, licenses, certificates, etc.), which are not to be (solely) saved in U-Boot environment, for whatever reason.
Current status --------------
A quick grep indicates that most, if not all boards locate U-Boot at the start of the flash.
The U-Boot environment is written to the start of the configured flash block. Prior to that, this block is erased, its content is lost.
Possible approach -----------------
Most CPUs start execution at flash address 0 or somewhere in this region at the reset ISR vector.
In case U-Boot is not located there but some flash sectors later, at this reset vector there has to be some architecture specific code block, which could be a - simple jump to U-Boot entry - dummy ISR table with reset vector pointing to U-Boot - specific trampoline code - ...
In other words, a few bytes (up to e.g. 1kB) of (static) binary data, generated at compile time.
This has to be put before the environment, either implicit or included at the start of "struct environment_s". The latter would of course break backward compatibility, at least without some additional code.
The variant of including this code into a specific block would again waste a flash block resp. mandate the presence of a VPD or similar.
Things to define / check ------------------------
- U-Boot entry point on non-PIC builds (U-Boot start != CONFIG_SYS_FLASH_BASE) - U-Boot on architectures not capable of a single jump forward by e.g. 32kB or 64kB - redundant environment - mixed flash/external environment - ...