Where to put Bootloader Key in Ram, what address is the last ram address

bootloadercmicrocontrollerram

I am programming a CDC Bootloader. What I want to do is to run the program, from there write a bootloader key to the ram at a specific address and watchdog reset the MCU. The Bootloader reads exactly the same address and checks if it has the bootloader key in it. If it is the bootloader key it will execute the bootloader protocol, otherwise start the sketch again.

Now the question is: What address to use? Ive heard that a few addresses of the ram pointer are reserved for some peripheral registers. Ive also heard about the stack management in ram. So what would be the best place to put such a magic bootloader key?

As an example on an Arduino Leonardo (32u4) with 2,5kb ram they save it at the 2kb address:
https://github.com/arduino/Arduino/blob/master/hardware/arduino/bootloaders/caterina/Caterina.c#L69

Any suggestions for a 16u2 and 32u2 with 500/1000 byte ram? Or maybe another way to pass the bootloader this information? Can anyone explain me why they used 0x0800 for a 32u4 or was this maybe just a 'random' place? I don't want to conflict with any program as less as possible and dont want to break programs with this kind of ram writing.

Edit:
It is important to find a normally not used ram address since you can revert this bootloader watchdog reset. See this:
https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/CDC.cpp#L96-L98

Best Answer

It really doesn't matter that much where you put your key, as long as your program and bootloader both agree on it.

You will just be setting a couple of bytes in RAM, setting the watchdog, then you should enter a while(1); loop so nothing else happens. You should also disable interrupts before you start as well. It doesn't matter if you overwrite memory used by the program, since that program is no longer running. Once the bootloader is finished and done with, it doesn't care what you do with that bit of RAM, so you can just use it as per normal in your program.

If you do want to "reserve" the memory in your program so it doesn't get used for anything else, you can place a variable in a separate section located at a specific address, and nothing else will be put there. Something like:

volatile uint32_t blkey __attribute__((section(".blkey")));

and then tell the compiler where that section is located by adding this to the linker:

-Wl,-section-start=.blkey=0x<ADDRESS>

That way you don't really care about what else is going on - that section is then set aside from the rest of your program.