BOOT SEQUENCE
References:
https://stackoverflow.com/questions/31244862/what-is-the-use-of-spl-secondary-program-loader/31252989#31252989
https://community.st.com/t5/stm32-mcus/stm32n6-fsbl-explained/ta-p/764307
https://community.st.com/t5/stm32-mcus/stm32n6-boot-rom-explained/ta-p/763648
BOOT SEQUENCE
How does a device starts? how does code go from storage to ram?

To load the firmware/OS first this that must happen is the initialisation of the ram, called Calibration. to do that:
- Boot ROM is the first immutable software that the processor executes, role of initialisation of the processor and loading the other pieces of software to be executed by the processor (often called First Stage Bootloader, U-Boot, BareBox). Each processor has it own way of finding this piece of software which can be found the reference manual.
First Stage Bootloader (FSBL) is the first piece of mutable software executed by a processor
- The FSBL is loaded into the SRAM of the processor (it isn't loaded into ram because the CPU doesn't know what RAM is connect to nor how to initialise it)
- The CPU starts executing the FSBL, which is responsible for initializing the system, configuring the hardware, and loading the application code from external memory into the internal or external memories for execution (step 4).
note: Firmware is an umbrella classification for software tightly coupled to hardware and stored in non-volatile memory.
BOOT SEQUENCE CORTEX-M
A microcontroller is a complete, self-contained computer system on a single chip, integrating a CPU, memory (RAM/ROM), and input/output peripherals for specific control tasks. In contrast, a CPU (often referred to as a microprocessor in this context) is only the processing unit, requiring external memory, storage, and peripherals to function.
Starting with the first address 0x0000 0000 it stores the value of initial value of MSP (the main stack pointer) and the second address 0x0000 0004 stores the value for the PC.
💡 The LR register is set to 0xFFFF FFFF

And the first routine be run is the Reset_Handler , this mean that the PC register is set to the address of this routine that rests the mcu (rest register the bss, calls the SystemInit routine and CopyDataInit routine.) then call main function
note:


In the arm architecture the LSB indicats if the the cpu is running the thump mode or arm mode
LSB = 1: thump mode
💡 arm cortex-m only supports the thump mode

boot pin
STM32 Boot Modes
microcontrollers support multiple boot modes that determine how the device initializes and where it fetches the initial code to execute. In this section, we’ll discuss the primary boot modes for STM32
microcontrollers.
STM32 Boot Mode Options
1) Main Flash Memory Boot:
The microcontroller boots from the main flash memory, where the user application is stored. This is the most common boot mode used in production devices.
2) System Memory Boot:
The microcontroller boots from the system memory, which contains the built-in bootloader. This mode is often used for firmware updates or initial programming through various interfaces such as UART, USB, or SPI.
3) Embedded SRAM Boot:
The micro-controller boots from the internal SRAM, which is mainly used for debugging or special purposes.

It’s very easy to identify the Boot0 pin in an STM32 microcontroller as you can see in the figure below. This is a special function pin for the microcontroller and is not multiplexed with any GPIO functionality.

On most STM32 microcontrollers, the Boot1 pin is multiplexed with a GPIO pin. It is essential to configure this GPIO pin correctly to be able to use it for boot mode selection, if needed. You need to refer to the specific STM32 datasheet for details on configuring the Boot1 pin.

SYSCFG memory remap register (SYSCFG_MEMRMP)
This register is used for specific configurations on memory remap:
• Two bits are used to configure the type of memory accessible at address 0x0000 0000.
These bits are used to select the physical remap by software and so, bypass the BOOT
pins.
• After reset these bits take the value selected by the BOOT pins. When booting from
main Flash memory with BOOT0 pin set to 0 this register takes the value 0x00.
In remap mode, the CPU can access the external memory via ICode bus instead of System
bus which boosts up the performance.


reference-manual-STM32F4.pdf
Kernel

synchronization: is the synchronization of tasks (using semaphores, mutexes, ..)
This a example from startup_stm32f401retx.s
/**
******************************************************************************
* @file startup_stm32f401retx.s
* @author Auto-generated by STM32CubeIDE
* @brief STM32F401RETx device vector table for GCC toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/* Call the clock system initialization function.*/
bl SystemInit
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The STM32F401RETx vector table. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word 0 /* Reserved */
.word EXTI16_PVD_IRQHandler /* EXTI Line 16 interrupt /PVD through EXTI line detection interrupt */
.word TAMP_STAMP_IRQHandler /* Tamper and TimeStamp interrupts through the EXTI line */
.word EXTI22_RTC_WKUP_IRQHandler /* EXTI Line 22 interrupt /RTC Wakeup interrupt through the EXTI line */
.word FLASH_IRQHandler /* FLASH global interrupt */
.word RCC_IRQHandler /* RCC global interrupt */
.word EXTI0_IRQHandler /* EXTI Line0 interrupt */
.word EXTI1_IRQHandler /* EXTI Line1 interrupt */
.word EXTI2_IRQHandler /* EXTI Line2 interrupt */
.word EXTI3_IRQHandler /* EXTI Line3 interrupt */
.word EXTI4_IRQHandler /* EXTI Line4 interrupt */
.word DMA1_Stream0_IRQHandler /* DMA1 Stream0 global interrupt */
.word DMA1_Stream1_IRQHandler /* DMA1 Stream1 global interrupt */
.word DMA1_Stream2_IRQHandler /* DMA1 Stream2 global interrupt */
.word DMA1_Stream3_IRQHandler /* DMA1 Stream3 global interrupt */
.word DMA1_Stream4_IRQHandler /* DMA1 Stream4 global interrupt */
.word DMA1_Stream5_IRQHandler /* DMA1 Stream5 global interrupt */
.word DMA1_Stream6_IRQHandler /* DMA1 Stream6 global interrupt */
.word ADC_IRQHandler /* ADC1 global interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word EXTI9_5_IRQHandler /* EXTI Line[9:5] interrupts */
.word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break interrupt and TIM9 global interrupt */
.word TIM1_UP_TIM10_IRQHandler /* TIM1 Update interrupt and TIM10 global interrupt */
.word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation interrupts and TIM11 global interrupt */
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare interrupt */
.word TIM2_IRQHandler /* TIM2 global interrupt */
.word TIM3_IRQHandler /* TIM3 global interrupt */
.word TIM4_IRQHandler /* TIM4 global interrupt */
.word I2C1_EV_IRQHandler /* I2C1 event interrupt */
.word I2C1_ER_IRQHandler /* I2C1 error interrupt */
.word I2C2_EV_IRQHandler /* I2C2 event interrupt */
.word I2C2_ER_IRQHandler /* I2C2 error interrupt */
.word SPI1_IRQHandler /* SPI1 global interrupt */
.word SPI2_IRQHandler /* SPI2 global interrupt */
.word USART1_IRQHandler /* USART1 global interrupt */
.word USART2_IRQHandler /* USART2 global interrupt */
.word 0 /* Reserved */
.word EXTI15_10_IRQHandler /* EXTI Line[15:10] interrupts */
.word EXTI17_RTC_Alarm_IRQHandler /* EXTI Line 17 interrupt / RTC Alarms (A and B) through EXTI line interrupt */
.word EXTI18_OTG_FS_WKUP_IRQHandler /* EXTI Line 18 interrupt / USBUSB On-The-Go FS Wakeup through EXTI line interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word DMA1_Stream7_IRQHandler /* DMA1 Stream7 global interrupt */
.word 0 /* Reserved */
.word SDIO_IRQHandler /* SDIO global interrupt */
.word TIM5_IRQHandler /* TIM5 global interrupt */
.word SPI3_IRQHandler /* SPI3 global interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word DMA2_Stream0_IRQHandler /* DMA2 Stream0 global interrupt */
.word DMA2_Stream1_IRQHandler /* DMA2 Stream1 global interrupt */
.word DMA2_Stream2_IRQHandler /* DMA2 Stream2 global interrupt */
.word DMA2_Stream3_IRQHandler /* DMA2 Stream3 global interrupt */
.word DMA2_Stream4_IRQHandler /* DMA2 Stream4 global interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word OTG_FS_IRQHandler /* USB On The Go FS global interrupt */
.word DMA2_Stream5_IRQHandler /* DMA2 Stream5 global interrupt */
.word DMA2_Stream6_IRQHandler /* DMA2 Stream6 global interrupt */
.word DMA2_Stream7_IRQHandler /* DMA2 Stream7 global interrupt */
.word USART6_IRQHandler /* USART6 global interrupt */
.word I2C3_EV_IRQHandler /* I2C3 event interrupt */
.word I2C3_ER_IRQHandler /* I2C3 error interrupt */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word SPI4_IRQHandler /* SPI4 global interrupt */
.size g_pfnVectors, .-g_pfnVectors
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak EXTI16_PVD_IRQHandler
.thumb_set EXTI16_PVD_IRQHandler,Default_Handler
.weak TAMP_STAMP_IRQHandler
.thumb_set TAMP_STAMP_IRQHandler,Default_Handler
.weak EXTI22_RTC_WKUP_IRQHandler
.thumb_set EXTI22_RTC_WKUP_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Stream0_IRQHandler
.thumb_set DMA1_Stream0_IRQHandler,Default_Handler
.weak DMA1_Stream1_IRQHandler
.thumb_set DMA1_Stream1_IRQHandler,Default_Handler
.weak DMA1_Stream2_IRQHandler
.thumb_set DMA1_Stream2_IRQHandler,Default_Handler
.weak DMA1_Stream3_IRQHandler
.thumb_set DMA1_Stream3_IRQHandler,Default_Handler
.weak DMA1_Stream4_IRQHandler
.thumb_set DMA1_Stream4_IRQHandler,Default_Handler
.weak DMA1_Stream5_IRQHandler
.thumb_set DMA1_Stream5_IRQHandler,Default_Handler
.weak DMA1_Stream6_IRQHandler
.thumb_set DMA1_Stream6_IRQHandler,Default_Handler
.weak ADC_IRQHandler
.thumb_set ADC_IRQHandler,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_TIM9_IRQHandler
.thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
.weak TIM1_UP_TIM10_IRQHandler
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_TIM11_IRQHandler
.thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak EXTI17_RTC_Alarm_IRQHandler
.thumb_set EXTI17_RTC_Alarm_IRQHandler,Default_Handler
.weak EXTI18_OTG_FS_WKUP_IRQHandler
.thumb_set EXTI18_OTG_FS_WKUP_IRQHandler,Default_Handler
.weak DMA1_Stream7_IRQHandler
.thumb_set DMA1_Stream7_IRQHandler,Default_Handler
.weak SDIO_IRQHandler
.thumb_set SDIO_IRQHandler,Default_Handler
.weak TIM5_IRQHandler
.thumb_set TIM5_IRQHandler,Default_Handler
.weak SPI3_IRQHandler
.thumb_set SPI3_IRQHandler,Default_Handler
.weak DMA2_Stream0_IRQHandler
.thumb_set DMA2_Stream0_IRQHandler,Default_Handler
.weak DMA2_Stream1_IRQHandler
.thumb_set DMA2_Stream1_IRQHandler,Default_Handler
.weak DMA2_Stream2_IRQHandler
.thumb_set DMA2_Stream2_IRQHandler,Default_Handler
.weak DMA2_Stream3_IRQHandler
.thumb_set DMA2_Stream3_IRQHandler,Default_Handler
.weak DMA2_Stream4_IRQHandler
.thumb_set DMA2_Stream4_IRQHandler,Default_Handler
.weak OTG_FS_IRQHandler
.thumb_set OTG_FS_IRQHandler,Default_Handler
.weak DMA2_Stream5_IRQHandler
.thumb_set DMA2_Stream5_IRQHandler,Default_Handler
.weak DMA2_Stream6_IRQHandler
.thumb_set DMA2_Stream6_IRQHandler,Default_Handler
.weak DMA2_Stream7_IRQHandler
.thumb_set DMA2_Stream7_IRQHandler,Default_Handler
.weak USART6_IRQHandler
.thumb_set USART6_IRQHandler,Default_Handler
.weak I2C3_EV_IRQHandler
.thumb_set I2C3_EV_IRQHandler,Default_Handler
.weak I2C3_ER_IRQHandler
.thumb_set I2C3_ER_IRQHandler,Default_Handler
.weak SPI4_IRQHandler
.thumb_set SPI4_IRQHandler,Default_Handler
.weak SystemInit
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/