Embedded Bootloaders Explained

Typically embedded bootloaders start life as a single program. As changes are introduced over time, the application needs a way to update itself. This is the genesis of all bootloaders. Here we will go through common embedded bootloader strategies and outline the pros and cons of each.

Simplest Bootloader

Here at Bermondsey Electronics, we like to keep our embedded bootloaders simple. The very simplest of all is to have a tiny program run to check code integrity, and carry out an update if one is needed. This super simple application might run a checksum over the code, or it might check if an update is available, and apply it if so.

Philosophies vary on how best this is carried out, but here we believe that bootloaders in embedded systems should not handle unnecessary communication. They should not have to activate radios or communication links to carry out its task. These are extra risks; the application itself can fetch an update and store it locally so the bootloader can apply the update. Doing it this way ensures the bootloader always has a way to load correct code into the target. This also means we do not have to update the embedded bootloader itself to change how we fetch and deliver updates to the product. Application updates can deliver new code to the target. This creates the following flow:

A diagram of a software process

AI-generated content may be incorrect.

This is about as simple as it gets. If the product loses power at any time, it’s recoverable. We never delete the bootloader, so the bootloader itself is always able to run. If the user powers us down, we can recover.

The downside to this is we probably have to hard code some limits to the embedded bootloader itself. We might lock down the maximum size of the application, the maximum size of the update, or possibly restrict where we store the new application. Depending on the application, these trade-offs may or may not be acceptable.

Advanced Bootloader

How do we safely have a bootloader in an embedded system which can automatically update itself? How do we make sure we have a product which can survive a failed attempt to perform an update? There are a few ways to achieve this. Here are some scenarios we may want to avoid:

  1. Broken application gets into the field
  2. Broken bootloader gets into the field
  3. Change method of delivering update to the target
  4. Unexpected power loss while updating bootloader
  5. Unrecoverable and broken application update

The common answer to all of these is the use of a multi-stage bootloader in an embedded system. We start with an immutable bootloader such as outlined above, and we introduce multiple stages to arrive at the application. This transforms the first stage bootloader into an even simpler application whose only job is to work out which second stage bootloader to run.

A diagram of a flowchart

AI-generated content may be incorrect.

This first stage is immutable, so it will never change. However it can now detect errors in second stage bootloaders. It can detect if one is current / latest. Crucially, if an error is detected, it can run another instead. Now we can start thinking about having the second stage embedded bootloader carry out self-updates, for example. We can begin to separate the updater application from the functional application. This can have benefits on low memory parts, since we no longer have to worry about application considerations like running other features alongside the main application.

Note some  hardware architectures can have issues with this configuration. Cortex-M processors support an interrupt offset vector which allows arbitrarily multiple interrupt vector tables. PIC24 supports two vector tables within one application, meaning exactly one vector table for a bootloader, and one for an application. One bootloader in an embedded system therefore cannot use interrupts. Depending on the application this could be restrictive.

Conclusions

We have presented two embedded bootloader architectures. The simpler of the two allows recovery from failure. The more complex allows more flexibility in updates, and allows the bootloader itself to be updated. Which is better for a particular application depends on the application.

Don’t just take our word for it. Hear from our customers.

Bermondsey Electronics

Contact Us

If you have questions about how we can help your business please complete the form below and we will be in touch shortly.

Alternatively, please call us on +44 (0)208 0650 162

Email : [email protected]