The use of the ESP8266 in the world of IoT

User avatar
By rab
#37553 Long posts with lots of questions, and once again I'm at work, so I'll try and give a quick answer to what I easily can.

Esptool2 (or the sdk equivalent tools) extract elf sections from a fully linked executable binary compiled for the xtensa core in the esp8266 and packages them into a format suitable for use on the device. The built in loader reads a header from the flash (first part of the image created by esptool2/other, which sets a number of options such as the flash size and mode, then loads the ram sections from from the flash to ram. Section lengths, ram positions and the program entry point are also in the header. The rom boot loader never touches the irom section. It then starts to run code from the ram section at the specified entry point. This will normally be SDK code. The SDK is then responsible for setting up the memory mapping (not the boot loader), after which the bulk of the sdk and user code is run from there.

The memory mapping works by mapping a 1mb chunk of flash to 0x40200000. So if your irom section is stored on flash from 0x10000 onwards (for example), it will be accessible at memory address 0x40210000. So the linker script needs to have this address specified as the base base address for this section, so that the code it creates will correctly work at this address once running on the device. Where you put this section in flash/mapped memory so doesn't matter so long as they match up (except at the very start where the header needs to be, and the very end where the sdk will write it's stored config).

rBoot is compiled and linked like any other app, because that's exactly what it is, it just does something a bit different and doesn't include any sdk code. It is made into a normal rom and flashed to the device in the normal way at 0x00000 (normal for a standard non-bootloaded app, the only type the rom bootloader can handle), but it has no irom section. Its ram sections are copied to ram where it is executed. It then copies a second stage loader to a spare area of memory, transfers execution to that code, which loads up the user app into the normal memory area (overwriting it's own main code), then jumps to the apps entry point. End result is indistinguishable from an app loaded by the rom bootloader, it was just achieved differently (i.e. we did it ourselves), which means we can do more things like choose from multiple roms to load, etc.
User avatar
By eriksl
#37557 Thanks for all of your information and your effort to explain! You really don't need to rush it though.

I am going to read the whole answer once more and also I am going to experiment with the esptool2 and I am going to read all blogs once again. I am sure there will come more questions in the process, take your time to anwer ;)
User avatar
By eriksl
#37643 I still don't understand everything (quite) but from read from your code (very well-written, compliments!, clean and easy to read), I just learned that the SPI actually starts with an header (which I already more or less knew about), and this header contains a number (arbitrary?) of sections: destination address + size. The boot loader then loops over them and copies each section to the destination address and voilà, the destination address can be iram, memory mapped i/o register space, anything you can think of! So that is how it works, yes?

So that is how the original start address of each segment that the linker produces in the ELF data ends up in the image/flash! And that is why no padding is needed like I do (32k...). I was really assuming sections should start at fixed offsets in the image.

One quick question, from one of your blogs/documents. You talk about two example addresses:
0x40200000 + 0x2000 + 0x10 = 0x40202010 or
0x40200000 + 0x82000 + 0x10 = 0x40282010
which in itself is actually quite clear. But exactly what is this address used for:
- image "slot" start address in the image in the rboot config struct (I think so)
- irom segment in the loader script (I don't think so)
Just to be sure.
User avatar
By eriksl
#37877 Richard, forget all my previous questions, I think I have figured out almost all of it from the source code now. I also even got it working for a single (small) rom.

There is one really important issue remaining though, please give your opinion.

It appears the stage2a code is copied to the top of the IRAM0 memory, apparently from 0x4010fcd4 onwards and it takes up 812 bytes there. My IRAM segment is currently 32kbyte minus 100 bytes in size. So it WILL overwrite the code when it's copied to IRAM. I think a crash will be the result, don't you?

It will be very hard to clean up some more IRAM space, but I will try.