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?
_attachments/Pasted image 20260530075331.png

To load the firmware/OS first this that must happen is the initialisation of the ram, called Calibration. to do that:

  1. 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

  1. 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)
  2. 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

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

image 2.png

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:

image.png

image.png

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

image.png

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.

image.png

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.

image.png

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.

image.png

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.

image.png

reference-manual-STM32F4.pdf

reference-manual-STM32F4.pdf

Kernel

_attachments/image 9.png

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****/