agentleFS
mohitmishra786mohitmishra786/low-level-dev-skills/skills/baremetal/bootloaders-embedded/SKILL.md

bootloaders-embedded

Skill290 starsChanged 7 months agoMITView on GitHub

Embedded bootloader skill for firmware update and app handoff. Use when writing a custom bootloader, jumping to application code, relocating VTOR, or implementing DFU/USB firmware update on Cortex-M. Activates on queries about bootloader jump, vector table relocation, application entry point, STM32 DFU, or dual-bank flash.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Write to scratch sector, verify CRC, then swap metadata pointer (A/B)

    line 104
  2. Distinctive:

    Never erase the only valid image without recovery path

    line 105

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

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 skills/baremetal/baremetal-startup and skills/baremetal/stm32-baremetal

Workflow

1. Memory layout (typical STM32)

RegionAddressSizeContent
Bootloader0x0800000016–64 KBBL code, update logic
Application0x08010000remainderApp vector + code

Linker script for app must set FLASH ORIGIN to app base; vector table must live at app base.

2. Valid application image check

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 section
#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

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 SCB->VTOR = APP_BASE early in Reset_Handler if startup assumes relocatable vector table.

4. Bootloader responsibilities

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

5. STM32 system memory DFU (factory 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.

6. Update safety

  • 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

7. Agent usage

/bootloaders-embedded Write STM32F4 jump-to-app at 0x08010000 with VTOR setup

Common Problems

SymptomCauseFix
HardFault after jumpSP invalid or Thumb bit missingValidate vectors; ensure reset | 1
IRQs hit bootloader handlersVTOR not relocatedSet SCB->VTOR before enabling IRQs
App OK standalone, fails via BLLinker still at 0x08000000Relink app with correct ORIGIN
UART garbage after jumpBL left UART runningDe-init or reset peripherals
Brick after OTAPower loss mid-eraseDual-bank or metadata rollback

Related Skills

  • skills/baremetal/baremetal-startup — vector table and Reset_Handler
  • skills/baremetal/stm32-baremetal — flash map and CMSIS
  • skills/baremetal/interrupts-and-exceptions-baremetal — NVIC disable pattern
  • skills/embedded/linker-scripts — VMA/LMA for split images
  • skills/embedded/openocd-jtag — recover bricked flash

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.