Skip to main content
Visitor II
October 12, 2021
Solved

How to Create a Super Simple Bootloader, Part 3: Developing the Boot Code - check if an initial SP is loaded at the start of flash

  • October 12, 2021
  • 3 replies
  • 2155 views

Hi,

I had a question regarding Bruno's excellent series on creating a simple bootloader.

In part 3, there is an if statement which checks if something has in fact been loaded into the applications's flash region:

// bootloader main.c
if( ( *(uint32_t *) FLASH_APP_ADDR ) & 0x2FFE0000 ) == 0x20000000 )
{
 // jump to app main...
}

The logical AND operation against the dereferenced FLASH_APP_ADDR with a mask that I don't understand, should yield an initial SP.

What does 0x2FFE0000 signify?

Many thanks,

Dan

    This topic has been closed for replies.
    Best answer by DRall.1

    You're right, I am overthinking it. And muddled myself :)

    To be fair, the video describes the magic number's purpose.

    However, it didn't work for me, as my top of stack is at address 0x20002000

    And, naturally, (FLASH_APP_ADDR + 4) is the reset_handler of the application

    To point out a mistake in my previous comment, I don't know why I thought the initial stack pointer was at the beginning of RAM otherwise there would be no stack!

    And no... I definitely don't want to test several values for a simple bootloader example. It was just trying to get my head around this simple concept.

    Many thanks. I think we can close this ticket :-)​

    3 replies

    Graduate II
    October 13, 2021

    It masks the decode for an address that resides in the first 128KB of SRAM, ie 0x20000000 thru 0x2001FFFF

    You could probably broaden the scope at this point these days, plus 0x20020000 is technically valid as it predecrements.

    DRall.1Author
    Visitor II
    October 13, 2021

    Thanks for your reply.

    In the example video, the size of RAM is 32k. In that respect, why is the operand not 0x2FFF8000?

    Is 0x2FFE0000 the worst case based on the maximum possible RAM size?

    In the video it explains that the expression should resolve to the initial stack pointer (at the beginning of the flash address for the app). I really should check the disassembly but i would expect the initial stack pointer to be set to an address that begins after the .bss and .data section, not 0x20000000 (very beginning of RAM)?

    I must have something else confused here. Is it clear where I might be going wrong with my understanding?

    If the initial SP dereferenced at FLASH_RAM_ADDR is e.g. 0x20000420 then the result of 0x2FFE0000 & 0x20000420 == 0x20000000

    Graduate II
    October 13, 2021

    You're perhaps over thinking it, it is a cheap and crude test. A value of 0x00000000 or 0xFFFFFFFF would fail it. These are the common erased values in STM32 parts. The 0x20xxxxxx range in the Cortex-M is decoded as RAM

    The GNU linker scripts typically place the stack pointer at the top-of-ram, Keil it has a defined size beyond .BSS

    You want to have a more comprehensive test that tests against half-a-dozen values/ranges, go to town..

    Remember the people making the videos were probably only tangentially involved in the original code development and choices.

    DRall.1AuthorAnswer
    Visitor II
    October 14, 2021

    You're right, I am overthinking it. And muddled myself :)

    To be fair, the video describes the magic number's purpose.

    However, it didn't work for me, as my top of stack is at address 0x20002000

    And, naturally, (FLASH_APP_ADDR + 4) is the reset_handler of the application

    To point out a mistake in my previous comment, I don't know why I thought the initial stack pointer was at the beginning of RAM otherwise there would be no stack!

    And no... I definitely don't want to test several values for a simple bootloader example. It was just trying to get my head around this simple concept.

    Many thanks. I think we can close this ticket :-)​