Writing on a magic RAM address to trigger a bootloader?
Hello!
I've been working with embedded software for a while now, but managed to avoid the nitty-gritty of bootloaders most of the time. Now on my current project I have some catching up to do.
We are working on top of the reference firmware for the ST25RU3993-EVAL. The bootloader here isn't executed every boot, instead it is summoned by an UART command, which fits what our application should do too. While studying the code I had some questions regarding how the bootloader is triggered. Here is the relevant section of code:
/* Whole SRAM: 0x20000000 - 0x20017FFF
Bootloader-MagicWord: 0x20017FF0 - 0x20017FFF (16 bytes)
Remaining SRAM: 0x20000000 - 0x20017FEF
*/
#define SYS_MEM_ADDR 0x1FFF0000
#define BOOTLOADER_MAGIC_INFO_ADDR 0x20017FF0
const char* BtlMagicInfo = ".EnterBooloader.";
static void bootloaderInit(void)
{
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
__set_MSP(*(__IO uint32_t*) SYS_MEM_ADDR);
void (*Bootloader)(void) = (void(*)(void)) *((uint32_t *) (SYS_MEM_ADDR + 4));
Bootloader();
while(1);
}
void bootloaderCheck(void)
{
if(0 == memcmp((const void*)BOOTLOADER_MAGIC_INFO_ADDR, BtlMagicInfo, strlen(BtlMagicInfo)))
{
*(uint32_t *)BOOTLOADER_MAGIC_INFO_ADDR = 0;
bootloaderInit();
}
}
void bootloaderEnterAndReset(void)
{
memcpy((void*)BOOTLOADER_MAGIC_INFO_ADDR, BtlMagicInfo, strlen(BtlMagicInfo));
HAL_NVIC_SystemReset();
while(1);
}Okay, so first of all lets see if I understood how this is supposed to work: When bootloaderEnterAndReset() gets called a magic word is written at a previously known RAM address and the MCU is reset. Since it is a soft reset, the magic word doesn't get erased and is checked in bootloaderCheck() (called first thing in main). If the magic word is there, bootloaderInit() performs the actual jump.
Almost all this seems clear and makes sense, I'm just having a hard time understanding how the RAM address works. It points to the last 16 bytes of RAM (MCU is a STM32L476, by the way), but there is no variable there, its just a raw address.
- Isn't this supposed to be a stack area then?
- From what I understand, the stack grows top-down, so aren't you overwriting the stack when copying the magic word to this address?
I thought that maybe these last 16 bytes were reserved in the linker script somehow, but it doesn't seem to be the case.
Am I on the right track here? Can someone shed some light on what trick am I missing?
Thanks a lot for taking the time to help and sorry for any English mistakes.
Edit: Had typed the wrong MCU model.
