The use of the ESP8266 in the world of IoT

User avatar
By rab
#37498
As far as I understand this would be the steps required:

compile boot loader, don't link

No, compile rBoot and link it as normal. Why wouldn't you link it?

compile sources, link

Yes, build your app as normal.

use esptool to convert elf files to two firmware files iram, irom

No, use esptool2 to produce a single app rom image (which contains all app parts).

create composite firmware file from iram, pad to 64k, then append boot loader+pad, config sector+pad, irom

If you want to put this into a single file you start with rBoot.bin, pad it to 4k (with 0xff), then either append a custom rBoot config padded to 4k or just append another 4k of blanks (0xff), then append the image produced above. This can then be flashed to 0x0000 and will install rBoot, the optional config (or a blank one that will be overwritten on first boot) and the actual app.

I was assuming that means you can't use the first 64 kbytes (0x10000) for irom and you need to pad over them in this way.

Don't know where you got this 64k from. The built in rom loader needs the iram/dram segments first (these are copied to actual ram) followed by the irom segment which is read directly from rom when used. So long as the order is correct it doesn't matter where the irom segment starts, so long as you set the address in the linker file appropriately. With rBoot (and the sdk loader) the irom segment is first so that it can have a known start point and no gap between it and the ram segments. If the ram segments were first you have to pad to have a known address for the rom segment. Only the first 8k are used for rBoot and the rom can follow straight after. In theory rBoot and config would fit fine in one 4k sector but it's not a good idea to erase and rewrite the bootloader sector every time you want to rewrite the config, for obvious reasons. The rom starts at 0x02000, but it contains a header before the actual code which is why the rom address is +0x10.
User avatar
By eriksl
#37537 Oh dear, you're so far ahead... I hope you answers to my questions will benefit many users, not just me.

It appears we need to go even more basic. You ask "where do I get this from"? That's indeed a good question. And yes, trust me, if there were any decent documentation, I would have known it all and I wouldn't have to ask ;) A good example is the ATmel AVR series of microprocessors. Everything and really everything is documented in a datasheet of over 250 pages including diagrams, examples and tables. With the esp2866 we don't have that luxury, the documentation is really only slightly helpful, I guess you know best ;) For some reason they don't want us to know the low level stuff (hardware and boot loader stuff), it's really a shame. To answer your question in this context: I could not find any documentation of the complete flashing procedure (low-level, not operational level), so I took some existing projects from which I knew they were working and I tried to find some concept behind it all and so I came to the conclusion that the layout of the flash would consist of 16 kbytes of iram, 16 kbytes of padding and then the irom contents (which could be located from that point onwards). This model has worked for me for this time, but is apparently wrong.

So then, can you please give a mini course for newbies on the flashing concept? As far as I know it works like this:
- compiler generates elf object files
- linker generates elf object file, which contains segment symbols (+ offsets)
- esptool per preference reads the elf file, splits it into iram sections and other sections (probably also discards some sections)
- from these two "parts" the "esptool" then generates one or two firmware files
- the firmware file(s) are not elf, they're just raw data/instructions, so the segment offsets/addresses are lost
- that's why I assume the the iram and non-iram segments need to be at fixed offsets in the firmware file
- apparently the esptool in flash mode does:
- send header that a.o. contains the flash size/layout, possibly also the offsets or the addresses where the segments start and/or the address of the start of the code function, where is this header stored if it's not in flash, actually?
- send data being flashed at 0x40200000 onwards, which is programmed using explicit flash_write functions, so it's offsets are address - 0x40200000 (including 4k padding etc.).

The whole bootloader thing also isn't quite clear to me, many questions. I think for a part that is because imho there are three bootloaders which add to the confusion:

- bootloader in rom
- original SDK "ota" bootloader
- rboot "ota" bootloader.

I was under the impression that the "rom" bootloader would have these functions:
- do some diagnostics and setup basic I/O (like bios)
- copy first 32k of flash into iram
- setup flash mapping
- jump to user code (but how does it lnow where the user code starts, maybe it's a fixed offset in iram?)

An "ota" (either sdk or rboot) boot loader would then, after that (very much simplified)
- check which slot is active
- set up alternate flash address mapping
- copy first 32k of flash + slot offset into iram
- jump to user code (determinded by? config struct?)

You say many of this is in the blogs and believe me, I've read them twice or more, all of them, interesting stuff for sure! But I keep having missing pieces. Maybe it's something I overlook.
User avatar
By eriksl
#37549
rab wrote:No, compile rBoot and link it as normal. Why wouldn't you link it?

I was under the impression the code needs to be at a certain offset (e.g. 0x0). I am talking about the real boot loader here, not the api code. I understand that that code must be linked in.

No, use esptool2 to produce a single app rom image (which contains all app parts).

I will take a look into your tool. I've git-cloned it. Now reading the code, very interesting ;)

If you want to put this into a single file you start with rBoot.bin, pad it to 4k (with 0xff), then either append a custom rBoot config padded to 4k or just append another 4k of blanks (0xff), then append the image produced above. This can then be flashed to 0x0000 and will install rBoot, the optional config (or a blank one that will be overwritten on first boot) and the actual app.

So the layout of such an image would be:

0x0000 rboot.bin 4k
............ padding with 0xff
0x1000 rboot config 4k (real or dummy)
0x2000 iram segment, 32k
0xa000 irom segment

That is all there is to it?

That is why I said, "compile rboot, don't link it", so it can be included+padded separately.

Don't know where you got this 64k from. The built in rom loader needs the iram/dram segments first (these are copied to actual ram)

Yes ok, clear. But how does it know where the iram segments end? The elf symbols are lost.

With rBoot (and the sdk loader) the irom segment is first so that it can have a known start point and no gap between it and the ram segments. If the ram segments were first you have to pad to have a known address for the rom segment.

Exactly!

So the way I do it now (32k iram segment (+32 k padding which apparently isn't necessary) and then the irom code, won't work if I use rboot, that's not going to work, the segments need to be other way around?

The rom starts at 0x02000, but it contains a header before the actual code which is why the rom address is +0x10.

Can you explain, is this header unique for rboot, is it always there, is it the header that esptools add?