Personal learning notes · Cortex-M · IAR · IAP bootloader
Scope: From MCU reset to applicationmain(), including IAP bootloader handover. RTOS scheduling and context switching are excluded.
This note focuses on the mechanisms that are easiest to confuse: vector-table lookup, MSP initialization, linker-defined memory layout, C runtime initialization, VTOR versus memory remapping, and bootloader handover.
1. The big picture
A Cortex-M application is not simply a collection of C functions stored in Flash. It is a firmware image with a specific memory layout, an entry point, and initialization requirements.
At reset, the processor needs to answer two questions:
- Where should the stack start?
- Where should execution begin?
The vector table provides both answers.
Normal boot sequence
1 | MCU reset |
There are three distinct layers:
| Layer | Responsibility |
|---|---|
| Cortex-M hardware | Initial stack and exception entry |
| Startup code | Prepare the MCU and enter the runtime |
| C runtime | Prepare C/C++ program memory and call main() |
Key idea: main() is not the processor’s actual entry point. A considerable amount of initialization happens before it.
2. Memory architecture and firmware layout
Medium depth
2.1 The address space
A typical STM32 has several memory regions:
| Memory | Typical address | Purpose |
|---|---|---|
| Flash | 0x08000000 |
Firmware and constant data |
| SRAM | 0x20000000 |
Runtime variables, stack, heap |
| Peripheral | 0x40000000 |
GPIO, UART, timers, etc. |
| System memory | Device-dependent | ROM bootloader and system functions |
These are address ranges in the processor’s memory map. The processor accesses them through addresses; it does not need a different instruction set to access Flash or SRAM.
For example:
1 |
|
This reads a 32-bit word from the memory mapped at that address.
2.2 Firmware image versus runtime memory
A firmware image is usually programmed into Flash, but the program does not necessarily execute using all its data directly from Flash.
Consider:
1 | int counter = 10; |
A typical arrangement is:
counter: initialized variable, stored initially in Flash but used in SRAM.status: zero-initialized variable, allocated in SRAM.version: constant data, typically stored in Flash.
This introduces an important distinction:
The firmware image describes initial contents; the runtime memory layout describes where the program uses those contents.
The linker decides where these sections are placed and how startup code initializes them.
3. Vector table and firmware image
Deep dive
3.1 Why does the vector table exist?
When the processor resets, it cannot call main() directly because it does not yet know where the application’s stack is or where its startup code begins.
It needs a standardized place to find these addresses.
That place is the vector table.
A vector table is an array of 32-bit entries. Each entry contains an address or initial value associated with the processor’s reset and exception/interrupt handling.
The first two entries are especially important:
| Offset | Entry | Meaning |
|---|---|---|
0x00 |
Initial MSP | Initial Main Stack Pointer |
0x04 |
Reset Handler | Address of startup code |
0x08 |
NMI Handler | Non-maskable interrupt handler |
0x0C |
HardFault Handler | Hard fault handler |
0x10 |
MemManage Handler | Memory management fault handler, where implemented |
The first entry is not a function address. It is a stack address.
The second entry is the function address at which execution starts.
3.2 Decode your actual BIN example
You previously inspected this binary dump:
1 | Offset Bytes |
Cortex-M stores these 32-bit values in little-endian format.
Little endian means the least significant byte is stored first.
For example:
1 | Bytes: F0 05 00 20 |
The decoded table is:
| Offset | Bytes | 32-bit value | Meaning |
|---|---|---|---|
0x00 |
F0 05 00 20 |
0x200005F0 |
Initial MSP |
0x04 |
D5 40 00 08 |
0x080040D5 |
Reset Handler |
0x08 |
61 65 00 08 |
0x08006561 |
NMI Handler |
0x0C |
65 5A 00 08 |
0x08005A65 |
HardFault Handler |
Notice the different address regions:
0x200005F0belongs to SRAM: this is the initial stack pointer.0x080040D5belongs to Flash: this is the Reset Handler.
This is exactly what we expect from a normal STM32 application.
3.3 Why does the Reset Handler address end in an odd number?
You may notice:
1 | 0x080040D5 |
The least significant bit is 1.
This is intentional.
Cortex-M processors execute Thumb instructions. A function pointer uses bit 0 to indicate Thumb state. The actual instruction address is aligned, while bit 0 carries the state indication.
So:
1 | Stored function address: 0x080040D5 |
Do not simply clear bit 0 when interpreting a vector-table entry. The processor expects the Thumb-state indication.
3.4 Your Intel HEX example
You also showed:
1 | :020000040800F2 |
This is not a raw BIN file. It is Intel HEX, a text representation of memory records.
The record format is:
1 | :LL AAAA TT [DD...] CC |
| Field | Meaning |
|---|---|
LL |
Number of data bytes |
AAAA |
16-bit address offset |
TT |
Record type |
DD |
Data bytes |
CC |
Checksum |
The first line:
1 | :020000040800F2 |
is an Extended Linear Address record:
02: two data bytes.0000: record offset.04: extended linear address record.0800: upper 16 bits of the address.F2: checksum.
It establishes the upper address portion as 0x0800.
The next record starts with:
1 | 40 09 00 20 D5 00 00 08 |
Decoding it gives:
1 | Initial MSP = 0x20000940 |
The same vector-table interpretation applies. Only the representation of the firmware file is different.
3.5 BIN versus HEX
| Feature | BIN | Intel HEX |
|---|---|---|
| Format | Raw binary bytes | ASCII text records |
| Address information | No explicit address in file | Encoded in records |
| Gaps | Usually represented by padding or omitted depending on export | Can be represented by missing address ranges |
| Common use | Programming at a known base address | Firmware distribution and programming |
A BIN file needs an external base address. Without that address, the bytes alone do not tell you where they belong in Flash.
A HEX file contains address information, so its records can describe data at different locations.
Remember: a BIN file beginning with a vector table is a common export arrangement, not a universal guarantee. Headers, padding, or custom image formats can precede it.
4. Cortex-M reset and startup sequence
Deep dive
4.1 What happens immediately after reset?
On a normal Cortex-M boot, the processor obtains two initial values from the boot-mapped vector table:
- The initial MSP value from offset
0x00. - The Reset Handler address from offset
0x04.
Conceptually:
1 | MSP = *(uint32_t *)(vector_base + 0x00); |
The processor then begins executing the Reset Handler.
This is hardware behavior. It does not require main() or your C runtime to run first.
The actual memory visible at the boot address depends on the device’s boot configuration and memory mapping.
4.2 What is Reset_Handler?
Reset_Handler is the first software entry point after the processor’s reset sequence.
It is usually implemented in assembly startup code.
Its job is to prepare the system for normal C execution.
A simplified conceptual startup sequence looks like this:
1 | Reset_Handler: |
This is illustrative pseudocode, not an exact startup file. Real startup code may use different branch instructions and runtime entry symbols.
4.3 What does SystemInit() do?
SystemInit() is usually provided by the STM32 device support package or project startup code.
Depending on the project, it may:
- Configure the clock tree.
- Set up the PLL.
- Configure the FPU.
- Set the vector table offset.
- Perform early MCU-specific initialization.
It is not a universal fixed sequence. Always inspect the actual implementation in your project.
4.4 What happens before main()?
The C runtime prepares the memory required by your application.
For example:
1 | int counter = 10; |
Before main():
countermust contain10.statusmust contain0.
The runtime initialization performs this work.
This leads to the next important topic: how the linker and startup code cooperate to prepare RAM.
5. MSP, linker layout, and C runtime initialization
Deep dive
5.1 Why is the initial MSP determined by the linker?
The processor needs a valid stack before it can execute normal C code.
But the processor does not know where your project wants the stack to be.
The linker knows the memory regions and section placement defined by the project configuration. It can therefore determine the stack region and provide its initial top address.
The initial MSP is commonly the top of the reserved stack region.
Remember that the Cortex-M stack normally grows downward, toward lower addresses.
For example, imagine this simplified SRAM layout:
1 | Higher SRAM addresses |
This is a conceptual layout only. Real section ordering and heap/stack placement depend on the linker configuration.
5.2 Understanding .data, .bss, stack, heap, and NOINIT
These names describe different types of runtime memory.
| Section / region | Purpose | Startup behavior |
|---|---|---|
.data |
Initialized global/static variables | Copy initial values from Flash to RAM |
.bss |
Zero-initialized global/static variables | Clear RAM to zero |
| Stack | Function calls, local variables, saved registers | MSP starts at stack top |
| Heap | Dynamic memory allocation | Managed by allocator |
NOINIT |
Memory that should retain its existing contents | Not initialized by normal C runtime |
Example:
1 | int counter = 10; // .data |
The .data and .bss sections are particularly important because RAM is not automatically initialized to the values required by the C program.
5.3 Why does .data need copying?
Consider:
1 | int counter = 10; |
The initial value 10 must be stored somewhere in the firmware image so it survives power loss.
Therefore, the initial value is stored in Flash.
However, the program expects counter to be a writable variable in SRAM.
The linker describes both locations:
1 | Flash: initial value = 10 |
At startup, the runtime copies the initial value from Flash into SRAM.
Conceptually:
1 | for (src = __data_load_start, |
This is illustrative pseudocode. Actual startup code uses linker-generated symbols and may copy multiple sections.
5.4 Why does .bss need clearing?
Consider:
1 | int status; |
The C language requires a static-storage-duration object without an explicit initializer to be zero-initialized.
The runtime therefore clears the corresponding RAM region:
1 | for (dst = __bss_start; dst < __bss_end; ) |
Again, this is conceptual code.
Without this step, status could contain whatever value was previously in that SRAM location.
5.5 What is NOINIT?
A NOINIT section is a memory region that startup code intentionally leaves untouched.
This is useful when data must survive a software restart or when another component has already prepared the memory.
Your previous IAP design uses this concept for the SRAM vector table:
- Bootloader copies the application vector table into SRAM.
- Application reserves the same SRAM area.
- C runtime must not clear or overwrite that area.
If the vector-table reservation were accidentally included in .bss, startup could erase the copied vector entries.
If it were included in .data, startup could overwrite them with the application’s initial data image.
So the reservation must be correctly placed and excluded from normal initialization.
5.6 Why did your two firmware images have different initial MSP values?
You showed two initial MSP values:
1 | Image A: 0x200005F0 |
The difference is:
1 | 0x20000940 - 0x200005F0 = 0x350 |
The key point:
The initial MSP is determined by the final linked memory layout, not simply by the configured stack size.
The linker may place different amounts of data into SRAM before the stack region. Differences can result from:
- More or fewer global/static variables.
- Different initialized or zero-initialized sections.
- Additional library or middleware data.
- Different alignment and section placement.
- Different linker configuration or memory regions.
- Different stack-region placement.
Identical stack sizes do not guarantee identical initial MSP addresses.
5.7 How to verify this in IAR
Rather than guessing from the address, inspect the linker output.
Useful files:
.icf: linker configuration file..map: linker-generated memory map.
Look for:
- SRAM memory definitions.
CSTACKandHEAPplacement.- Read/write sections.
- Zero-initialized sections.
- Any
NOINITsection. - The initial stack symbol, often associated with
CSTACKboundaries.
Exact symbol names depend on the IAR runtime and project configuration.
The important investigation is:
- Find the SRAM region.
- Identify where
.dataand.bssare placed. - Find the stack reservation.
- Determine its top address.
- Compare that address with the first word of the vector table.
Do not assume every project uses the same section ordering.
6. Vector table relocation: VTOR versus memory remapping
Deep dive
This is one of the most important distinctions in your previous bootloader design.
The two mechanisms solve related problems, but they operate at different levels:
- VTOR changes where the processor looks for the vector table.
- Memory remapping changes which physical memory is visible at a particular address.
6.1 What is VTOR?
VTOR stands for Vector Table Offset Register.
It is part of the Cortex-M System Control Block (SCB).
1 | SCB->VTOR = 0x08010000; |
This tells the processor to use the vector table located at 0x08010000.
Imagine an application is stored at:
1 | Application Flash base = 0x08010000 |
Its vector table is also located at that address.
Setting VTOR to this address allows the processor to find the application’s exception and interrupt handlers there.
The vector table itself does not move. Only the address used for vector-table lookup changes.
6.2 How does the processor find an interrupt handler?
For a Cortex-M processor, the vector table contains 16 core exception entries before the external interrupt entries.
For an external interrupt:
1 | Vector index = 16 + IRQ number |
The handler entry address is:
1 | Handler entry address = VTOR + 4 × vector index |
For example, if an external interrupt has IRQ number 5:
1 | Vector index = 16 + 5 = 21 |
The processor reads the handler address from that location and uses it to enter the interrupt handler.
This explains why an incorrect VTOR can cause the processor to jump to an invalid address when an interrupt occurs.
6.3 Your application at 0x08010000
Suppose the Flash layout is:
1 | 0x08000000 +----------------------+ |
For a Cortex-M4 such as the STM32F469, the straightforward approach is:
1 | SCB->VTOR = 0x08010000; |
Now the processor uses the application’s vector table directly from Flash.
No vector-table copy to SRAM is required.
The address must satisfy the VTOR alignment requirements of the particular Cortex-M implementation. Do not assume any arbitrary Flash address is valid.
6.4 What does memory remapping do?
Some STM32 devices provide a SYSCFG memory-remapping mechanism.
For example, an applicable STM32 may support:
1 | __HAL_SYSCFG_REMAPMEMORY_SRAM(); |
This changes which memory is visible through the address alias at 0x00000000.
Conceptually:
Before remapping:
1 | Address 0x00000000 |
After SRAM remapping:
1 | Address 0x00000000 |
The important point is that remapping does not copy data. It changes the memory mapping.
If you previously copied the application’s vector table into SRAM, remapping can make that SRAM vector table visible at the zero address.
6.5 Reconstructing your previous SRAM vector-table design
Your previous design can be understood as follows.
Step 1 — Bootloader copies the application vector table to SRAM.
1 | Application vector table in Flash |
Step 2 — Application reserves the beginning of SRAM.
The application reserves a region for the vector table.
You previously mentioned reserving 48 words:
1 | 48 × 4 = 192 bytes = 0xC0 |
Conceptually:
1 | SRAM |
The reserved region must not be overwritten by the application’s C runtime initialization.
Step 3 — Application remaps SRAM to address zero.
1 | __HAL_SYSCFG_REMAPMEMORY_SRAM(); |
The processor’s vector lookup at address zero now accesses the SRAM alias.
Step 4 — Interrupts use the SRAM vector table.
The vector table is physically in SRAM, but it is also visible through the zero-address alias.
The application code can still execute from its normal Flash address.
6.6 Does Cortex-M3 require SRAM remapping?
No. This is an important correction to an earlier explanation.
Cortex-M3 supports VTOR. STM32F103, which uses Cortex-M3, also supports VTOR.
SRAM remapping is an alternative mechanism that may be useful for particular boot or compatibility designs. It is not a requirement imposed by Cortex-M3.
| Mechanism | What changes? | Example |
|---|---|---|
| VTOR | Vector-table lookup base | SCB->VTOR = 0x08010000 |
| SRAM remapping | Memory visible at an address alias | SRAM becomes visible at 0x00000000 |
6.7 Is 48 words enough for your vector table?
Not necessarily.
You need to consider:
- The exact STM32 part number.
- The number of implemented core and external interrupt vectors.
- The required vector-table alignment.
- The size of the SRAM reservation.
- The linker placement of the reservation.
For example, a table with 16 core entries and 43 external interrupt entries needs:
1 | 16 + 43 = 59 words |
A 192-byte reservation would not hold that complete table.
This is an example of why the exact MCU reference manual and startup vector definition matter. Do not copy a reservation size from another project without checking it.
6.8 Which method should you use?
For your STM32F469 application, prefer the direct VTOR method:
1 | SCB->VTOR = APP_ADDRESS; |
It is simpler and avoids the need to:
- Copy the vector table into SRAM.
- Reserve the beginning of SRAM.
- Protect the reservation from runtime initialization.
- Remap SRAM to address zero.
Keep the SRAM-remapping method in your notes because it helps explain your older design and is useful when working with devices or boot architectures that need it.
7. IAP bootloader → application handover
Deep dive
7.1 What is IAP?
IAP means In-Application Programming.
In a typical STM32 bootloader design, the bootloader can:
- Receive a firmware image.
- Erase and program the application Flash region.
- Validate the image.
- Transfer execution to the application.
A simplified Flash layout:
1 | Flash |
The bootloader and application are separate firmware images with separate vector tables and linker configurations.
7.2 Why is jumping to an application different from resetting?
When the MCU performs a hardware reset, the processor enters its reset sequence and initializes its architectural state according to the hardware reset behavior.
But when the bootloader jumps to the application, there is no hardware reset.
The processor continues running with much of its existing state.
For example:
- Peripheral registers may retain their previous configuration.
- NVIC interrupt enable and pending states may remain.
- SysTick may still be running.
- The clock configuration may have been changed by the bootloader.
- The processor may have a different stack configuration or interrupt state.
Therefore, a bootloader must prepare the system before transferring control.
7.3 What does the application need from the bootloader?
The application vector table contains two important initial values:
1 | APP_ADDRESS + 0x00 → Initial MSP |
For example:
1 | APP_ADDRESS = 0x08010000 |
The bootloader must:
- Validate that the application image is usable.
- Stop or disable interrupt sources as appropriate.
- Stop SysTick.
- Clear or disable relevant NVIC interrupt states.
- Set the application’s vector-table base.
- Load the application’s initial MSP.
- Branch to the application’s Reset Handler.
The application then runs its own startup sequence.
7.4 Conceptual C implementation
The following shows the essential operations, but is not production-ready code:
1 |
|
Important implementation caveat: Changing MSP inside an ordinary C function and then calling another C function is potentially unsafe. The compiler may generate stack accesses or function epilogues based on the original stack. A production bootloader normally uses a carefully controlled assembly handover (or a suitable naked function with an assembly sequence) to load MSP and branch without using the old stack afterward.
The example illustrates the required values and operations, not a complete safe implementation.
7.5 Why does the application run its startup code again?
After the bootloader branches to the application’s Reset Handler, the application starts from its own startup entry.
1 | Bootloader |
The application’s startup code initializes its own .data and .bss, prepares the runtime, and calls main().
This is why the application should be built as a standalone image with its own vector table and startup code.
However, remember: the startup code running again does not mean the MCU has been reset. The application’s peripherals and clocks may still be in the state left by the bootloader.
7.6 Application validation
Before jumping, don’t blindly trust the two vector-table words.
At minimum, consider checking:
- The MSP lies within the application’s permitted SRAM range.
- The MSP meets the required alignment.
- The Reset Handler points into an allowed executable region.
- The Reset Handler has the expected Thumb-state bit.
- The image passes its integrity check, such as CRC or a cryptographic signature.
The exact validation rules depend on your memory layout and security requirements.
7.7 A useful mental model
Think of bootloader handover as preparing a new program environment, not rebooting the MCU.
The bootloader must provide the application with the conditions it expects:
| Requirement | Who prepares it? |
|---|---|
| Application vector-table base | Bootloader |
| Application initial MSP | Bootloader |
| Valid application image | Bootloader |
.data initialization |
Application runtime |
.bss initialization |
Application runtime |
| Application peripherals and clock assumptions | Bootloader and/or application startup, by design |
main() execution |
Application runtime |
8. Practical inspection and debugging with IAR
Medium depth
This section connects the concepts to your actual development workflow.
You don’t need to memorize every startup symbol. You need to know where to look when something goes wrong.
8.1 Understand the startup files
In an IAR STM32 project, look for files such as:
1 | startup_stm32xxxx.s |
Their roles are different:
| File | Responsibility |
|---|---|
startup_stm32xxxx.s |
Reset Handler, vector table, initial startup sequence |
system_stm32xxxx.c |
System-level configuration, often including SystemInit() |
.icf |
Linker memory regions and section placement |
.map |
Final linked memory layout and symbol information |
The exact filenames depend on the STM32 device and project.
8.2 IAR runtime entry point
You may see a symbol such as:
1 | __iar_program_start |
This is associated with the IAR runtime startup process.
It is not the same symbol as the ARM Compiler entry point __main.
A common conceptual IAR startup flow is:
1 | Reset_Handler |
The exact order and implementation depend on the startup file and runtime configuration.
You may also encounter __low_level_init(). It is an IAR runtime hook that can be used for early initialization and can affect normal data initialization behavior. Check the IAR documentation and your actual project implementation before changing it.
Important distinction: SystemInit() is generally part of the MCU support/startup layer; __iar_program_start is part of the IAR runtime. They have different responsibilities.
8.3 A useful debugging sequence
Set breakpoints at these locations:
| Breakpoint | What to investigate |
|---|---|
Reset_Handler |
Did the processor enter the expected startup code? |
SystemInit() |
Are clocks and early hardware settings configured correctly? |
__iar_program_start |
Did control reach the IAR runtime? |
__low_level_init() |
Is early runtime initialization being customized? |
main() |
Has startup completed successfully? |
You can also inspect:
SCB->VTOR- MSP
- The first two vector-table entries
.dataand.bssaddresses- The application Flash base
- The linker map
8.4 A practical investigation exercise
Suppose your application is stored at 0x08010000, but it fails immediately after the bootloader jumps to it.
Investigate in this order:
- Read the first two words at
0x08010000. - Check that the MSP points into valid SRAM.
- Check that the Reset Handler points into the application Flash region.
- Check that VTOR is set to
0x08010000. - Check that interrupts are not firing through the wrong vector table.
- Break at the application’s
Reset_Handler. - Continue through
SystemInit()and IAR runtime initialization. - Check whether
main()is reached.
This sequence follows the actual startup dependency chain instead of guessing at the cause.
9. Complete boot sequence: one-page reference
Normal hardware boot
1 | Hardware reset |
IAP handover
1 | Bootloader |
In the IAP path, the bootloader performs the initial handover in software. There is no hardware reset between the two firmware images.
10. Quick reference
Important registers and functions
| Name | Purpose |
|---|---|
SCB->VTOR |
Selects vector-table base |
__set_MSP(value) |
Sets Main Stack Pointer |
__get_MSP() |
Reads Main Stack Pointer |
__disable_irq() |
Disables configurable interrupts globally |
__DSB() |
Data Synchronization Barrier |
__ISB() |
Instruction Synchronization Barrier |
SystemInit() |
Project/device-specific early initialization |
Reset_Handler |
Firmware startup entry |
__iar_program_start |
IAR runtime startup entry |
__low_level_init() |
Optional IAR early initialization hook |
__HAL_SYSCFG_REMAPMEMORY_SRAM() |
Enables SRAM remapping on supported STM32 devices |
Important concepts
| Concept | Remember it as |
|---|---|
| Vector table | Where the processor finds initial stack and exception handlers |
| Initial MSP | Top of the initial main stack |
| Reset Handler | First software startup entry |
| VTOR | Where the processor looks for the vector table |
| Memory remapping | Which physical memory appears at an address alias |
.data |
Initialized variables copied into RAM |
.bss |
Zero-initialized variables |
NOINIT |
Memory intentionally left untouched by runtime initialization |
| Linker | Decides memory layout and section placement |
| C runtime | Prepares the C program environment before main() |
Five distinctions worth remembering
- Vector table vs startup code: The vector table tells the processor where to start; startup code prepares the application.
- MSP vs stack size: MSP is an address; stack size is a memory reservation.
- Flash image vs RAM runtime: Initial variable values may live in Flash but be used from RAM.
- VTOR vs remapping: VTOR changes the vector lookup base; remapping changes the memory visible at an address.
- Application jump vs hardware reset: A branch to Reset Handler does not reset peripheral or processor state.
11. Self-check questions
Try answering these without looking at the previous sections.
Q1. Immediately after a normal Cortex-M reset, where does the processor get its initial MSP and Reset Handler address?
Q2. Why does the first vector-table entry point to SRAM while the second usually points to Flash?
Q3. If two firmware images have identical stack and heap sizes, why might their initial MSP values still differ?
Q4. Why must a bootloader jump to the application’s Reset Handler instead of directly calling main()?
Q5. What is the difference between changing VTOR and remapping SRAM to address zero?
Q6. Why must an SRAM vector-table reservation be excluded from .data and .bss initialization?
Q7. After an IAP jump, why might an application behave differently from one started by a hardware reset?
12. Answers
Q1. Initial MSP and Reset Handler lookup
The processor reads the first two 32-bit entries from the boot-mapped vector table. Entry 0 supplies the initial MSP; entry 1 supplies the Reset Handler address.
Q2. Why SRAM and Flash?
The stack is a runtime memory structure, so it resides in writable SRAM. The startup code normally resides in nonvolatile Flash.
Q3. Why can initial MSP differ?
The linker determines the stack’s actual placement. Other RAM sections, alignment, and linker configuration can change the stack’s location even when its reserved size stays the same.
Q4. Why jump to Reset_Handler?
The Reset Handler performs startup work, including low-level initialization and entering the C runtime. Calling main() directly would bypass those required steps.
Q5. VTOR versus remapping?
VTOR changes the address used for vector-table lookup. Memory remapping changes which memory is visible through a particular address alias, such as 0x00000000.
Q6. Why protect the SRAM vector table?
Otherwise, runtime initialization could overwrite the vector entries copied by the bootloader, breaking exception and interrupt handling.
Q7. Why can IAP startup differ from hardware reset?
An IAP jump does not perform a hardware reset. Peripheral configuration, clock settings, interrupt states, and other hardware state may be inherited from the bootloader.
Final mental model
If you remember only one chain, remember this:
1 | Vector table |
And if you remember only one distinction about IAP:
A bootloader jump transfers execution; it does not recreate the hardware reset state.
That distinction explains many of the precautions required when designing a reliable bootloader.
End of class note.