Help with RIOT OS bootloader

Hi guys. I’m new to RIOT OS, I’m working on the firmware update side of things. I’m trying to understand how the firmware update mechanism works. I have referred to the documentation and gone through the code. But I have some questions that I need answered. I haven’t found a clear answer to them. I was hoping some of you experienced folks could help me out.

  1. Does SUIT or Riotboot take care of verifying and validating the firmware file? Which module is responsible for this.
  2. Based on what factors is the slot actually selected by the boot loader after a firmware update. Is it just the integrity of the file and passing of the verification and validation or something more as well.
  3. Does the firmware verification take place right after the firmware is written to the flash or after a reboot?
  4. Can the RIOT bootloader be modified as per my need?
  5. Is the RIOT bootloader itself upgradable over the air?

Hi and welcome to RIOT! To answer your questions:

  1. Does SUIT or Riotboot take care of verifying and validating the firmware file? Which module is responsible for this.

SUIT takes care of that. After the firmware is written to the target slot, it’s hash is compared with the signed hash in the manifest. When the hash matches, the firmware slot header is marked as valid. Riotboot will then just select the slot with the highest version number that is marked valid.

  1. Based on what factors is the slot actually selected by the boot loader after a firmware update. Is it just the integrity of the file and passing of the verification and validation or something more as well.

Riotboot just selects the slot with the highest version number that has a valid header.

  1. Does the firmware verification take place right after the firmware is written to the flash or after a reboot?

The firmware is verified after it has been written to flash (by the old firmware)

  1. Can the RIOT bootloader be modified as per my need?

Yes. The default riotboot is very minimal, but there are versions to accept a firmware via USB DFU or via UART. (These do not verify a firmware signature).

  1. Is the RIOT bootloader itself upgradable over the air?

Yes, you can erase and re-write the bootloader with the flash page API, but this is not someting that already exists as a function you can just call. You need to keep in mind a few things:

  • You can’t iteratively download the bootloader as it’s done with the regular firmware. The regular firmware is written to the inactive slot, so when the download gets interrupted no harm is done as the slot is not yet marked as valid. If your bootloader download gets interrupted as you write it to the destination, you’d end up with a dead system upon next reboot. So you’d either need to keep the bootloader in RAM or write it to external storage first. This still leaves you vulnerable for power loss when you write the bootloader, but that’s much more managable.
  • You can’t change the partition layout retroactively. That means you can’t grow the number of flash sectors that the bootloader occupies once you have devices in the field.

Thanks for your response. However i have a few questions more.

SUIT takes care of that. After the firmware is written to the target slot, it’s hash is compared with the signed hash in the manifest. When the hash matches, the firmware slot header is marked as valid. Riotboot will then just select the slot with the highest version number that is marked valid.

Where does this happen? I went through the code but couldn’t find the place where the firmware is hash verified, I can only see the manifest being verified after the manifest is downloaded. Also, I can see the code which downloads the manifest file, but I cant see the code that downloads the slot0 or slot1 file.

Riotboot just selects the slot with the highest version number that has a valid header.

Ok, is there any sort of brick protection? Like if I push an incomplete or a buggy firmware for update by accident and my device downloads it, the hash gets verified and the slot is marked as valid, but lets say the firmware has a bug which causes it to keep resetting, So is there any mechanism to revert to the older firmware or to the previous slot or atleast be able to start the networking to be able to download a new firmware when available?

The firmware is verified after it has been written to flash (by the old firmware)

So this is done by SUIT itself or do I need to add code in the firmware to do this?

You can’t iteratively download the bootloader as it’s done with the regular firmware.

How can I do this? how can I get my device to download a separate bootloader code (Assuming that SUIT can only download the manifest, slot0 and slot1 file)?

Where does this happen? I went through the code but couldn’t find the place where the firmware is hash verified

This happens here

So is there any mechanism to revert to the previous slot?

We don’t have this yet. One way to do this would be to enable the watchdog in the bootloader and write some magic value to a .noinit region in RAM that is the same across firmware and bootloader. If the firmware then does not service the watchdog / clear the magic value, the bootloader could mark that firmware slot as invalid, which reverts to the previous firmware in the other slot.

But we don’t have such a mechanism yet. You can also do this entirely in your firmware and call riotboot_flashwrite_invalidate_latest() if your tests fail, but that would not protect you against a firmware that is completely non-functional - only a bootloader modification could.

how can I get my device to download a separate bootloader code

SUIT is flxible enough to allow for multiple payloads, but I don’t know how to do this either.

If you use CoAP, you can get a file using nanocoap_vfs_get_url() or nanocoap_get_blockwise_url_to_buf() but then you’d still need to do the siganture verification manually.

This happens here

Ok, And where is the piece of code that downloads the slot0 and slot1 file? I can’t find it in the code.

That is here. If you are running from slot0 it will download the slot1 file (and write it to slot1) and vice versa.