baremetal-startup
Skill290 starsChanged 7 months agoMITView on GitHub
Bare-metal startup skill for reset-to-main bring-up. Use when writing startup code, vector tables, .data/.bss init, stack setup, or crt0 for Cortex-M/RISC-V. Activates on queries about reset vector, VTOR, startup.s, bss init, or bare-metal entry point.
In this repository142 other files it gives its agents.
- AGENTS.mdAGENTS.md
- custom-allocatorsSkill
- numa-programmingSkill
- af-xdpSkill
- dpdkSkill
- io-uringSkill
- adc-dac-baremetalSkill
- bootloaders-embeddedSkill
- datasheet-and-refmanual-readingSkill
- dma-baremetalSkill
- gpio-baremetalSkill
- interrupts-and-exceptions-baremetalSkill
- low-power-embeddedSkill
- mmio-and-bit-manipulationSkill
- peripherals-from-datasheetSkill
- spi-i2c-baremetalSkill
- stm32-baremetalSkill
- timers-pwm-baremetalSkill
- uart-serial-baremetalSkill
- binutilsSkill
- dynamic-linkingSkill
- elf-inspectionSkill
- linkers-ltoSkill
- bazelSkill
- build-accelerationSkill
- cmakeSkill
- conan-vcpkgSkill
- include-what-you-useSkill
- makeSkill
- mesonSkill
- ninjaSkill
- static-analysisSkill
- code-generation-and-backendsSkill
- compiler-frontendSkill
- compiler-optimizations-deepSkill
- jit-compilationSkill
- llvm-ir-and-passesSkill
- llvm-passesSkill
- mlirSkill
- clangSkill
- cpp-modulesSkill
- cpp-templatesSkill
- cross-gccSkill
- gccSkill
- llvmSkill
- msvc-clSkill
- pgoSkill
- abi-and-calling-conventionsSkill
- branch-prediction-and-speculationSkill
- cpu-pipelines-and-hazardsSkill
- memory-hierarchy-and-cachesSkill
- virtual-memory-paging-and-tlbSkill
- concurrency-debuggingSkill
- core-dumpsSkill
- debug-optimized-buildsSkill
- dwarf-debug-formatSkill
- gdbSkill
- lldbSkill
- embedded-rustSkill
- freertosSkill
- The first 60 shown.
The file
Files
Bare-Metal Startup
Purpose
Guide agents through bare-metal startup from reset to main(): reset and exception vectors, .data/.bss initialization, stack and heap setup, C runtime integration with linker scripts, and common Cortex-M and RISC-V bring-up bugs.
When to Use
- Firmware hangs before reaching
main() - Porting to a new MCU without vendor HAL
- Writing custom
startup.sorReset_Handler - Integrating with
skills/embedded/linker-scripts - Debugging uninitialized globals or stack overflows at boot
Workflow
1. Boot sequence mental model
Power-on / reset
├── CPU loads SP from vector[0]
├── CPU branches to Reset_Handler from vector[1]
├── Reset_Handler: init clocks (optional), copy .data, zero .bss
├── Configure stack pointer (if not already from vector)
├── Call SystemInit() / platform_init()
└── Call main() — must not return (loop or WFI)2. Cortex-M vector table
On Cortex-M, the vector table starts at address 0 or a relocatable base (VTOR):
| Index | Entry |
| 0 | Initial stack pointer (_estack) |
| 1 | Reset_Handler |
| 2 | NMI_Handler |
| 3 | HardFault_Handler |
| 4+ | IRQ handlers per NVIC |
/* startup.s — minimal Cortex-M */
.syntax unified
.thumb
.section .isr_vector,"a",%progbits
.global g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
/* ... device IRQ vectors from vendor CMSIS ... */
.section .text.Reset_Handler
.thumb_func
.global Reset_Handler
Reset_Handler:
ldr r0, =_sidata /* .data load address (LMA) */
ldr r1, =_sdata /* .data VMA start */
ldr r2, =_edata
b LoopCopyDataInit
CopyDataInit:
ldr r3, [r0], #4
str r3, [r1], #4
LoopCopyDataInit:
cmp r1, r2
blt CopyDataInit
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2], #4
LoopFillZerobss:
cmp r2, r4
blt FillZerobss
bl SystemInit
bl main
b ./* Linker symbols — declared extern in startup */
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;3. VTOR relocation (Cortex-M)
#include "core_cm4.h" /* CMSIS */
void relocate_vector_table(uint32_t base) {
SCB->VTOR = base & 0xFFFFFF80U; /* must be aligned per ARM ref manual */
__DSB();
__ISB();
}Bootloader jumping to app often requires setting VTOR to the application's vector table address (e.g., 0x08020000 on STM32 flash).
4. RISC-V startup (overview)
/* entry.S — simplified */
.section .text.entry
.global _start
_start:
la sp, _stack_top
la t0, _bss_start
la t1, _bss_end
clear_bss:
beq t0, t1, bss_done
sw zero, 0(t0)
addi t0, t0, 4
j clear_bss
bss_done:
call main
j .Trap vector: mtvec for M-mode; see skills/platform/riscv-privileged.
5. crt0 responsibilities
| Task | Who does it |
Copy .data LMA→VMA | Reset_Handler / crt0 |
Zero .bss | Reset_Handler |
| Init stack | Vector[0] or explicit sp |
Heap (_sbrk) | Optional; libc or custom |
| C++ constructors | __libc_init_array() if using full libc |
| FPU enable | SystemInit on Cortex-M4F/M7 |
6. Linker script integration
_estack = ORIGIN(RAM) + LENGTH(RAM);
_sidata = LOADADDR(.data);Cross-link skills/embedded/linker-scripts for MEMORY/SECTIONS layout.
7. Agent usage examples
/baremetal-startup My STM32 never reaches main — what should Reset_Handler do?
/baremetal-startup How do I relocate the vector table after bootloader jump?Common Problems
| Symptom | Cause | Fix |
| HardFault immediately | Stack pointer invalid | Set _estack to valid RAM top |
| Globals wrong at boot | .data not copied | Copy LMA→VMA in Reset_Handler |
| BSS non-zero | .bss not zeroed | Add bss clear loop |
| IRQs don't fire | VTOR points to wrong table | SCB->VTOR = app_vector_addr |
main returns into garbage | No loop after main | while(1) or WFI loop |
| C++ static init crash | Constructors before clocks | Call SystemInit first |
Related Skills
skills/embedded/linker-scripts—_estack, LMA/VMA, section placementskills/baremetal/interrupts-and-exceptions-baremetal— vector table IRQ entriesskills/baremetal/bootloaders-embedded— VTOR relocation on app jumpskills/embedded/openocd-jtag— halt atReset_Handlerwith GDBskills/low-level-programming/assembly-arm— Thumb-2 syntaxskills/platform/riscv-privileged— RISC-V trap setup
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
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.

