rBoot – A new boot loader for ESP8266

As promised here is my new boot loader for the ESP8266 – rBoot.

Advantages over SDK supplied bootloader:

  • Open source (written in C) – this is the big one.
  • Supports any number of roms.
  • Roms can be different sizes.
  • Rom slots can be used for resource storage as well as bootable apps (and benefit from the OTA update system).
  • Can use the full size of the SPI flash (see below).
  • Rom slots can be altered after deployment (with care!).
  • Earlier rom validation (less prone to errors).
  • Can try multiple backup roms (without needing to reboot).
  • Rom selection by GPIO (e.g. hold down a button when powering on to start a recovery rom).
  • Wastes no stack space  (SDK boot loader uses 144 bytes).
  • Documented config structure (easy to configure from user code).

Disadvantages over SDK supplied bootloader:

  • Not compatible with sdk libupgrade (but equivalent source included, based on open source copy shipped with earlier SDKs, so you can easily update your existing OTA app use this new code).
  • Requires you to think slightly more about your linker scripts, rather than just using the pair supplied with the SDK (but it’s not really that difficult – if you’re programming in C it’ll be well within your capabilities).

Problems common to both:

  • You still need to relink user code against multiple different linker scripts depending where you intend to place it on the flash, because the memory mapped position of the .irom0.text section needs to be known at link time. This also prevents you moving roms around at will once they have been compiled.
  • Only 8MBit of flash can be memory mapped at a time (the SDK bootloader allows at most the first 2 x 8Mbit chunks to be used for roms, rBoot doesn’t have this limit, on a 32MBit flash you can have 4 x 8MBit roms), see memory mapping imitation for more details.

Source code

I’ve decided to start putting my source code on GitHub, it’ll be easier to maintain keep my blog tidier.

https://github.com/raburton

20 thoughts on “rBoot – A new boot loader for ESP8266”

  1. Hi Richard,

    I have created a test project with rboot with 32M(1024 + 1024) flash banks. However when I fist run the project, I get a Fatal exceptions right when my code tries to connect to wifi using internally saved wifi credentials.

    While debugging, I noticed this,

    rBoot v1.4.2 – richardaburton@gmail.com
    Flash Size: unknown
    Flash Mode: QIO
    Flash Speed: 40 MHz

    this would suggest rboot is unable to read flash size from the header section. Any idea why that would be. I am using this command to burn the images to ESP8266 12 E (32Mbit)

    esptool.py –port /dev/ttyUSB0 –baud 115200 write_flash -fm qio -fs 32m-c1 0x0000 rboot.bin 0x02000 user1.4096.new.6.bin 0x102000 user2.4096.new.6.bin 0x3fc000 esp_init_data_default.bin 0x3fe000 blank.bin

    1. System booting up …
      ESP8266 : SSID FRAMEWORK : INPUT MODE = HARDCODED
      ESP8266 : SSID FRAMEWORK : CONFIG MODE = WEBCONFIG
      ESP8266 : SSID FRAMEWORK : Wifi connected user cb function set !
      ESP8266 : SSID FRAMEWORK : Running !
      internal saved ssid valid. Using that
      ankit
      casa2016
      Fatal exception 9(LoadStoreAlignmentCause):
      epc1=0x4020245f, epc2=0x00000000, epc3=0x00000000, excvaddr=0x4010045b, depc=0x00000000

      ets Jan 8 2013,rst cause:2, boot mode:(3,7)

      load 0x40100000, len 1328, room 16
      tail 0
      chksum 0x12
      load 0x3ffe8000, len 604, room 8
      tail 4
      chksum 0x34
      csum 0x34

      rBoot v1.4.2 – richardaburton@gmail.com
      Flash Size: unknown
      Flash Mode: QIO
      Flash Speed: 40 MHz

      Booting rom 0.
      ����n��r��n|�
      l
      lll`��r�l�j����: sta(5c:cf:7f:a3:a3:38)
      add if0
      *******************************
      ESP8266 SERIAL IP BRIDGE
      *******************************

  2. Not sure it has anything to do with you. I originally installed sming with Chocolatey on windows (the recommended way) and there is even a command line for update the installation. For some reason Basic_rBoot is not added to my installation.
    So I just cloned the repository to another c:\tools folder and tried to build Basic_rBoot and get the following error(among others):
    app/application.cpp: In function ‘void OtaUpdate()’:
    app/application.cpp:61:23: error: ‘RBOOT_SPIFFS_0’ was not declared in this scope
    otaUpdater->addItem(RBOOT_SPIFFS_0, SPIFFS_URL);

  3. I am wondering why is .irom0.text section separate from the app sections (I mean user code not the bootloader)? Can’t we have one big firmware binary instead of two?

    1. By reading your other relevant articles it appears new v1.2 format produces all sections as close to each other as possible which is what I wanted. So I should check out the new format. 🙂

  4. Good afternoon ,
    Is it possible to write this command:
    esptool.py –port COM7 write_flash -fs 8m 0x00000 rboot.bin 0x02000 rom0.bin 0x82000 rom1.bin 0xfc000 blank4.bin
    as follows:
    esptool.py –port COM7 write_flash -fs 8m 0x00000 rboot.bin 0x01000 rom0.bin 0x81000 rom1.bin 0xfc000 blank4.bin

    1. No. 0x01000 is where the rBoot config is stored so your first rom will be corrupted. The second rom can go at 0x81000 if you want, or at 0x80000, or even lower if the first rom doesn’t reach there. If you do this you’ll need to change the linker script for rom1 to reflect this different flash location. You would also need to create a custom rBoot config and write it to 0x01000 so it knows where to look for the second rom. The default generated config expects the second rom to be at half chip size + 0x02000. This does waste 0x02000 bytes of flash but keeps things simple and symmetrical and you can always write your own config if you want full control. If you are writing your own rBoot config you can divide the chip up any way you want (and you aren’t limited to just two roms).

        1. The exact size of rBoot depends on what options you have enabled, for me it usually comes out at just over 2k. Either way, rBoot config is still at 0x1000 so you can’t write the rom there. You could move the config into the same sector as the boot loader, but that would be a bad idea because the config gets rewritten at times and you don’t want to risk corrupting the bootloader with a bad write. If you are really that desperate for another 4k use an ESP board with a bigger flash.

          1. Good afternoon ,
            Flash sector size is 4KB or 0x1000
            memory ESP 0x2000 – is 2 flash sector.
            rboot takes less than 3000 bytes or less than 1 sector of flash .
            Thus, 4096 bytes (0x1000) is much larger than the size of rboot.
            second sector jn 0x1001 to 0x2000, will always be empty.
            Do you agree with that?

          2. Nikolay, please read the comments I have already written (or the rBoot documentation) as I have now answered your question several times. To answer it a again: rBoot config is stored in the second sector.

  5. I’m busy working with this device at the moment, and looking to start implementing my own bootloader (just add custom encryption and that kind of thing etc) in the next week or so. Yours looks like a perfect starting point, really appreciate you sharing it. I will have to do quite a bit of makefile/linker hacking I presume, but nothing new there. Again, thank you.

    1. Glad it might be useful for you. If you’re making something open source feel free to contribute patches back to rBoot and we might be able to make it an official feature. Although I’ve been asked about firmware encryption with rBoot before and I couldn’t see how you could add more than trivial protection. All you’ll need to do to beat the encryption is decompile the boot loader and see how it works.

      1. For me, I just want to be able to send an encrypted firmware file to the user for someone to bootload without them being able to load it into their own ESP for example. It means hard coding a few keys in the bootloader, or at some other location in flash though, which is never ideal unless they’re in a HSM. I’ll admit though, I haven’t even investigated whether its possible to lock down the flash from a read – so this is still early days. No point in having an encryption enabled bootloader if anyone can simply read the entire flash binary from the outside once you do load it.

        1. To the best of my knowledge the esp8266 has no mechanism to prevent you reading the flash. Not that it matters because even if it did the flash is a separate chip so it could easily be removed and read with an SPI programmer if someone wanted your code. So the entire thing could be copied directly to another device or the bootloader could be decompiled, keys extracted and firmware decrypted for use elsewhere.

          1. Hmm, yeah, does really seem like a waste of time then if its going to be superficial. I’ll still give your bootloader a go though, at an undetermined time in the not so distant future…. Just need to get all my ducks in a row before hand.

Leave a Reply