bootloaders-embedded
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEmbedded Bootloaders
嵌入式Bootloaders
Purpose
用途
Guide agents through embedded bootloader fundamentals: vector table relocation, safe handoff from bootloader to application, flash partitioning, and basic firmware-update patterns (UART, USB DFU, or custom protocol) on Cortex-M and similar MCUs.
引导开发者掌握嵌入式Bootloader的核心知识:向量表重定位、Bootloader到应用的安全切换、闪存分区,以及Cortex-M和类似MCU上的基础固件更新模式(UART、USB DFU或自定义协议)。
When to Use
适用场景
- Application must run at non-zero flash offset (e.g. )
0x08010000 - Implementing OTA or USB DFU without vendor HAL
- Debugging "app works when flashed alone but not via bootloader"
- Integrating with and
skills/baremetal/baremetal-startupskills/baremetal/stm32-baremetal
- 应用需在非零闪存偏移地址运行(例如 )
0x08010000 - 不使用厂商HAL实现OTA或USB DFU
- 调试“单独烧录应用正常,但通过Bootloader启动异常”问题
- 与 和
skills/baremetal/baremetal-startup集成skills/baremetal/stm32-baremetal
Workflow
工作流程
1. Memory layout (typical STM32)
1. 内存布局(典型STM32)
| Region | Address | Size | Content |
|---|---|---|---|
| Bootloader | | 16–64 KB | BL code, update logic |
| Application | | remainder | App vector + code |
Linker script for app must set to app base; vector table must live at app base.
FLASH ORIGIN| 区域 | 地址 | 大小 | 内容 |
|---|---|---|---|
| Bootloader | | 16–64 KB | Bootloader代码、更新逻辑 |
| 应用 | | 剩余空间 | 应用向量表 + 代码 |
应用的链接脚本必须将 设置为应用基地址;向量表必须位于应用基地址处。
FLASH ORIGIN2. Valid application image check
2. 验证应用镜像有效性
Before jump, verify:
App vector[0] (initial SP) points into RAM region
App vector[1] (Reset) points into flash region and has Thumb bit set (LSB=1)
Optional: CRC or magic word in app metadata sectionc
#define APP_BASE 0x08010000U
static int app_valid(uint32_t base)
{
uint32_t sp = *(uint32_t *)base;
uint32_t reset = *(uint32_t *)(base + 4);
if (sp < SRAM_BASE || sp > SRAM_END)
return 0;
if ((reset & 1U) == 0U)
return 0;
if (reset < base || reset > FLASH_END)
return 0;
return 1;
}跳转前需验证:
App vector[0](初始栈指针SP)指向RAM区域
App vector[1](Reset向量)指向闪存区域且Thumb位已设置(最低位LSB=1)
可选:验证应用元数据段中的CRC或魔术字c
#define APP_BASE 0x08010000U
static int app_valid(uint32_t base)
{
uint32_t sp = *(uint32_t *)base;
uint32_t reset = *(uint32_t *)(base + 4);
if (sp < SRAM_BASE || sp > SRAM_END)
return 0;
if ((reset & 1U) == 0U)
return 0;
if (reset < base || reset > FLASH_END)
return 0;
return 1;
}3. Cortex-M handoff sequence
3. Cortex-M切换流程
c
typedef void (*app_entry_t)(void);
void jump_to_app(uint32_t app_base)
{
uint32_t sp = *(uint32_t *)app_base;
uint32_t reset = *(uint32_t *)(app_base + 4);
/* Disable interrupts and de-init peripherals/boot-owned hardware */
__disable_irq();
SysTick->CTRL = 0;
for (int i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFFU;
NVIC->ICPR[i] = 0xFFFFFFFFU;
}
SCB->VTOR = app_base;
__set_MSP(sp);
__DSB();
__ISB();
app_entry_t entry = (app_entry_t)reset;
entry(); /* does not return */
}Application must set early in if startup assumes relocatable vector table.
SCB->VTOR = APP_BASEReset_Handlerc
typedef void (*app_entry_t)(void);
void jump_to_app(uint32_t app_base)
{
uint32_t sp = *(uint32_t *)app_base;
uint32_t reset = *(uint32_t *)(app_base + 4);
/* 禁用中断并初始化外设/Bootloader占用的硬件 */
__disable_irq();
SysTick->CTRL = 0;
for (int i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFFU;
NVIC->ICPR[i] = 0xFFFFFFFFU;
}
SCB->VTOR = app_base;
__set_MSP(sp);
__DSB();
__ISB();
app_entry_t entry = (app_entry_t)reset;
entry(); /* 不会返回 */
}如果启动代码假设向量表可重定位,应用必须在 早期设置 。
Reset_HandlerSCB->VTOR = APP_BASE4. Bootloader responsibilities
4. Bootloader职责
Power-on
├── Init minimal clock + UART/USB for update
├── Check update flag in RTC backup / GPIO strap
├── If update requested → receive image, verify, program flash
└── Else if valid app → jump_to_app()
└── Else stay in bootloader shell上电
├── 初始化最小时钟 + UART/USB用于更新
├── 检查RTC备份区 / GPIO引脚的更新标志
├── 如果请求更新 → 接收镜像、验证、烧录闪存
└── 否则如果应用有效 → 调用jump_to_app()
└── 否则停留在Bootloader交互界面5. STM32 system memory DFU (factory ROM)
5. STM32系统内存DFU(工厂ROM)
STM32 chips expose USB DFU in system memory when BOOT0=1. Custom bootloaders are separate — do not confuse ROM DFU with user flash BL.
当BOOT0=1时,STM32芯片会在系统内存中启用USB DFU。自定义Bootloader是独立的——请勿将ROM DFU与用户闪存中的Bootloader混淆。
6. Update safety
6. 更新安全性
- Write to scratch sector, verify CRC, then swap metadata pointer (A/B)
- Never erase the only valid image without recovery path
- Reset watchdog only after verified commit
- 先写入临时扇区,验证CRC,再交换元数据指针(A/B分区)
- 没有恢复路径时,切勿擦除唯一有效的镜像
- 仅在验证提交完成后重置看门狗
7. Agent usage
7. 技能调用方式
/bootloaders-embedded Write STM32F4 jump-to-app at 0x08010000 with VTOR setup/bootloaders-embedded Write STM32F4 jump-to-app at 0x08010000 with VTOR setupCommon Problems
常见问题
| Symptom | Cause | Fix |
|---|---|---|
| HardFault after jump | SP invalid or Thumb bit missing | Validate vectors; ensure |
| IRQs hit bootloader handlers | VTOR not relocated | Set |
| App OK standalone, fails via BL | Linker still at | Relink app with correct ORIGIN |
| UART garbage after jump | BL left UART running | De-init or reset peripherals |
| Brick after OTA | Power loss mid-erase | Dual-bank or metadata rollback |
| 症状 | 原因 | 解决方法 |
|---|---|---|
| 跳转后出现HardFault | 栈指针SP无效或缺失Thumb位 | 验证向量表;确保 `reset |
| 中断触发Bootloader处理函数 | VTOR未重定位 | 启用中断前设置 |
| 单独运行应用正常,通过Bootloader启动异常 | 链接脚本仍指向 | 使用正确的ORIGIN重新链接应用 |
| 跳转后UART输出乱码 | Bootloader未关闭UART | 初始化或重置外设 |
| OTA后设备变砖 | 擦除过程中断电 | 使用双区分区或元数据回滚机制 |
Related Skills
相关技能
- — vector table and Reset_Handler
skills/baremetal/baremetal-startup - — flash map and CMSIS
skills/baremetal/stm32-baremetal - — NVIC disable pattern
skills/baremetal/interrupts-and-exceptions-baremetal - — VMA/LMA for split images
skills/embedded/linker-scripts - — recover bricked flash
skills/embedded/openocd-jtag
- — 向量表与Reset_Handler
skills/baremetal/baremetal-startup - — 闪存映射与CMSIS
skills/baremetal/stm32-baremetal - — NVIC禁用模式
skills/baremetal/interrupts-and-exceptions-baremetal - — 拆分镜像的VMA/LMA设置
skills/embedded/linker-scripts - — 恢复变砖的闪存
skills/embedded/openocd-jtag