PineTime bootloader improvements

From PINE64
Revision as of 17:42, 18 November 2020 by JF (talk | contribs) (Add bootloader/application boundaries)
Jump to navigation Jump to search

Introduction

This pages describes the improvements I propose to make to the bootloader and OTA to make the whole process more reliable.

My goals are:

  • KISS : Keep It Stupid Simple. Simple code contains less bugs than complicated/complex code.
  • As reliable as possible. 100% reliability is not feasible with the current hardware (no physical reset button, no bootloader in ROM code,...), but let's try to reach 99.9% reliability :)
  • Provide a read-only factory image we'll be able to restore in case of unrecoverable errors during OTA
  • Provide a way to upgrade the bootloader
  • Provide a way to switch from MCUBoot to NRF bootloaders

Current memory map

MemoryMap.png

Internal flash:

  • Bootloader contains the MCUBoot bootloader.
  • Boot log is currently not used. Can be use to provide reboot logs to the application
  • App is the PRIMARY SLOT for MCUBoot : the firmware that is currently running.
  • Scratch is used by MCUBoot as temporary storage for swap operation

External flash:

  • Bootloader assets : boot logo
  • OTA : SECONDARY SLOT for MCUBoot. During OTA, this is where the new version of the firmware is stored.
  • FS : space available for the application firmware.

This memory map allows a strong boundary between the bootloader and the application :

  • The bootloader is ran by the MCU at reset time and loads its boot logo from the SPI flash
  • The bootloader (MCUBoot) swaps images from primary and secondary slots if necessary
  • The bootloader starts the watchdog
  • The bootloader jumps to 0x8000 to run the application

The application don't know anything about the bootloader except that:

  • it must be linked @0x8000
  • it must refresh the watchdog periodically
  • it must store the image for OTA at a specific location in the external SPI flash memory

In this configuration, the boot logo is part of the bootloader, not of the application : the same logo will be displayed whatever application firmware will be loaded.

Changes

Factory image

The factory image is a 'light' build of InfiniTime that contains the bare minimum code to provide OTA to the user : basic UI, BLE and OTA. No apps, no fancy functionalities,... This factory image will be stored in the "bootloader assets" area of the external flash memory.

This factory image will be restored either automatically, when the bootloader detect it cannot boot from primary slot (App in internal memory) and secondary slot (OTA from exeternal). The user can also request to restore this factory image if necessary (using the button?).

Bootloader assets

Graphics can be compressed using a simple RLE encoding. RLE encoding on 1 bits (2 colors images) is very efficient (115200KB -> 1-5KB).

In order to simplify the code, the graphics will be stored into the bootloader code instead of storing them into the external flash:

- Less code.
- Easier to document : 1 specific logo = bootloader mode
- Do not have to worry about the dynamic size of the logo (the binary size of the graphics will vary with the content when they are RLE encoded).

Bootloader

  • Display the bootloader version on the screen and expose the version to the application firmware
  • Provide a way to revert the firmware to the last working version AND to the factory firmware
  • Display status and progression (progress bar similar to wasp-reloader, color code,...)
  • Test as much as possible

Upgrade & Reloader

The reloader is a tool that allows to upgrade the current version of the bootloader AND to switch from MCUBoot to NRF and vice versa.

How does it work ?

  • Upgrade
    • The reloader is first OTAed like any firmware upgrade.
    • When the system resets, MCUBoot swaps the application firmware with the reloader. The reloader upgrade the current bootloader and resets the system. It does NOT flag the image as validated. It resets the MCU.
    • The new version of MCUBoot notice that the last upgrade is not validated and reverts to the firmware that was running just before.
    • Voilà, you're running your firmware and a new version of the bootloader
  • Switch bootloader
    • The reloader is first OTAed like any firmware upgrade.
    • When the system resets, MCUBoot swaps the application firmware with the reloader. The reloader overwrite the current bootloader with a new one and reset.
    • The new bootloader is running.
  • Switch
    • From InfiniTime to wasp-os : the reloader contains the NRF Bootloader and Softdevice. This bootloader provides the OTA mecanism out of the box. Wasp-os is downloaded when the NRF bootloader is running
    • From wasp-os to InfiniTime : the reloader contains the factory image (infinitime-factory). The complete version of InfiniTime will be OTAed when this factory image is running.

Discussions

Boot Logo : embedded into the bootloader binary vs stored in the external SPI flash

Fixed vs dynamic memory map