#flash #nor #boot #memory #rt500 #mx #flex-spi

mimxrt500-bootstub

Glue code to make cortex-m-rt work with NXP i.MX RT500 series chips when booting from FlexSPI NOR flash

3 releases (breaking)

0.3.0 Sep 11, 2023
0.2.0 Sep 11, 2023
0.1.0 Sep 11, 2023

#615 in Operating systems


Used in 2 crates

MIT license

20KB
280 lines

Some helper macros to generates a NOR flash header ("flash control block"), initial vector table, and small shim code that can be written to the start of the NOR flash connected to FlexSPI0 on an i.MX RT500-series chip to deal with its unusual requirements before jumping into a more normal-looking embedded Rust application linked to somewhere else in memory -- typically a later page or block of the same Flash memory, but that's not required.

This series of chips has no built-in flash memory and so instead has a boot ROM that probes various peripherals to try to find some external memory containing a boot image. One option is a NOR flash connected to FlexSPI0, but that requires some chip-specific header information in the first page of flash that is intermingled with the initial vector table, and is thus incompatible with the image layout typically generated by the cortex-m-rt crate.

To allow using cortex-m-rt in the normal way, this crate can help generate a small stub image to write into the first page of memory, separately from the main application, which then expects to find a normal-looking cortex-m-rt-based application at some other memory address and begins executing it.

This does mean "wasting" at least a page of flash memory and having a redundant extra vector table used only by the boot stub, but that's typically a small price to pay for the convenience of meeting the expectations of the embedded Rust ecosystem for Cortex-M-based platforms.

Bootstub Styles

For flexibility for different application needs, this library offers two different variations of the boot stub generator macro. Each application must include exactly one call to exactly one of these.

  • bootstub_builtin is the most straightforward option, which embeds a bootstub directly inside the application and transfers control to the application code using the vector table generated by the cortex-m-rt linker script.

    This approach provides the most "normal" development experience, but at the expense of slightly bloating your application image by embedding the boot stub directly into it.

  • bootstub_standalone is a more specialized option which allows building an executable that is only a boot stub, expecting to find the real application vector table at a fixed memory location.

    This approach in theory allows flashing the bootstub image only once and then flashing normal application code with its vectors at the designated address as a separate operation. The bootstub and the application are independent from one another and can be updated separately.

Flash Control Block

The RT500 boot ROM also requires the NOR flash to contain a Flash Control Block, which is a data structure that both declares that the flash memory is intended as boot media and helps the boot ROM to configure the FlexSPI0 peripheral to read from it efficiently.

If your flash does not include a flash control block then the boot ROM will not consider the NOR flash as a candidate boot medium.

Use [fcb] to declare a Flash Control Block, which should then be linked at the appropriate location using your linker script.

No runtime deps