Skip to content

Commit fbf3cce

Browse files
matthijskooijmanfpistm
authored andcommitted
Jump to bootloader from asm block
This ensures that the SP is not modified after loading it and ensures a jump instruction is used. The assembly code was based on micropython and another STM32 core: https://github.com/micropython/micropython/blob/f6375ac3ebac28656a0a757952d32c265b1ba7aa/ports/stm32/powerctrl.c#L71-L78 https://github.com/GrumpyOldPizza/arduino-STM32L4/blob/bacc184288a4644b2ee6a97672334983f3e788ab/system/STM32L4xx/Source/boot_stm32l4xx.c#L159-L166
1 parent 7278930 commit fbf3cce

File tree

1 file changed

+15
-24
lines changed

1 file changed

+15
-24
lines changed

libraries/SrcWrapper/src/stm32/bootloader.c

+15-24
Original file line numberDiff line numberDiff line change
@@ -95,33 +95,24 @@ WEAK void jumpToBootloaderIfRequested(void)
9595
#ifdef USBCON
9696
USBD_reenumerate();
9797
#endif
98-
void (*sysMemBootJump)(void);
9998

10099
uint32_t sys = bootloaderAddress();
101100

102-
/**
103-
* Set jump memory location for system memory
104-
* Use address with 4 bytes offset which specifies jump location
105-
* where program starts
106-
*/
107-
sysMemBootJump = (void (*)(void))(*((uint32_t *)(sysMem_addr + 4)));
108-
109-
/**
110-
* Set main stack pointer.
111-
* This step must be done last otherwise local variables in this function
112-
* don't have proper value since stack pointer is located on different position
113-
*
114-
* Set direct address location which specifies stack pointer in SRAM location
115-
*/
116-
__set_MSP(*(uint32_t *)sysMem_addr);
117-
118-
/**
119-
* Jump to set location
120-
* This will start system memory execution
121-
*/
122-
sysMemBootJump();
123-
124-
while (1);
101+
// This is assembly to prevent modifying the stack pointer after
102+
// loading it, and to ensure a jump (not call) to the bootloader.
103+
// Not sure if the barriers are really needed, they were taken from
104+
// https://github.com/GrumpyOldPizza/arduino-STM32L4/blob/ac659033eadd50cfe001ba1590a1362b2d87bb76/system/STM32L4xx/Source/boot_stm32l4xx.c#L159-L165
105+
asm volatile(
106+
"ldr r0, [%[sys], #0] \n\t" // get address of stack pointer
107+
"msr msp, r0 \n\t" // set stack pointer
108+
"ldr r0, [%[sys], #4] \n\t" // get address of reset handler
109+
"dsb \n\t" // data sync barrier
110+
"isb \n\t" // instruction sync barrier
111+
"bx r0 \n\t" // branch to bootloader
112+
: : [sys] "l"(sys) : "r0"
113+
);
114+
115+
__builtin_unreachable();
125116
}
126117
}
127118

0 commit comments

Comments
 (0)