关于 baremetal-startup
面向从复位到 main() 的裸机启动开发 Agent,涵盖 Cortex-M 和 RISC-V。内容包括向量表、内存初始化、链接脚本集成及常见启动故障。
主要功能
- 01复位处理程序与向量表配置
- 02.data 和 .bss 初始化
- 03Cortex-M VTOR 重定位
- 04RISC-V 启动概览
- 05链接脚本集成
- 06启动故障诊断
适用场景
- 01排查固件无法到达 main()
- 02为没有厂商 HAL 的 MCU 移植
- 03编写自定义 startup.s 或 Reset_Handler
- 04修复全局变量未初始化或启动栈问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill baremetal-startup安装后在 Claude Code 中输入/baremetal-startup确认已加载。
详细介绍
裸机启动
用途
指导 Agent 完成从复位到 main() 的裸机启动:复位和异常向量、.data/.bss 初始化、栈和堆设置、C 运行时与链接脚本集成,以及常见的 Cortex-M 和 RISC-V 启动问题。
适用场景
- 固件在到达
main()之前挂起 - 在不使用厂商 HAL 的情况下移植到新的 MCU
- 编写自定义
startup.s或Reset_Handler - 与
skills/embedded/linker-scripts集成 - 调试未初始化的全局变量或启动时的栈溢出
工作流
1. 启动序列心智模型
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 向量表
在 Cortex-M 上,向量表从地址 0 或可重定位的基址(VTOR)开始:
| 索引 | 条目 |
|---|---|
| 0 | 初始栈指针(_estack) |
| 1 | Reset_Handler |
| 2 | NMI_Handler |
| 3 | HardFault_Handler |
| 4+ | NVIC 中对应的 IRQ 处理程序 |
/* 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 重定位(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();
}
引导加载程序跳转到应用程序时,通常需要将 VTOR 设置为应用程序向量表的地址(例如,STM32 闪存上的 0x08020000)。
4. RISC-V 启动(概述)
/* 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 .
陷阱向量:M-mode 使用 mtvec;参见 skills/platform/riscv-privileged。
5. crt0 的职责
| 任务 | 执行者 |
|---|---|
将 .data 从 LMA 复制到 VMA | Reset_Handler / crt0 |
将 .bss 清零 | Reset_Handler |
| 初始化栈 | Vector[0] 或显式设置 sp |
堆(_sbrk) | 可选;由 libc 或自定义代码提供 |
| C++ 构造函数 | 使用完整 libc 时调用 __libc_init_array() |
| 启用 FPU | Cortex-M4F/M7 上的 SystemInit |
6. 链接脚本集成
_estack = ORIGIN(RAM) + LENGTH(RAM);
_sidata = LOADADDR(.data);
结合 skills/embedded/linker-scripts,交叉参考 MEMORY/SECTIONS 布局。
7. Agent 使用示例
/baremetal-startup My STM32 never reaches main — what should Reset_Handler do?
/baremetal-startup How do I relocate the vector table after bootloader jump?
常见问题
| 症状 | 原因 | 修复方法 |
|---|---|---|
| 立即发生 HardFault | 栈指针无效 | 将 _estack 设为有效的 RAM 顶部地址 |
| 启动时全局变量错误 | 未复制 .data | 在 Reset_Handler 中将 LMA 复制到 VMA |
| BSS 非零 | 未将 .bss 清零 | 添加 BSS 清零循环 |
| IRQ 不触发 | VTOR 指向错误的表 | SCB->VTOR = app_vector_addr |
main 返回后执行垃圾代码 | main 后没有循环 | 使用 while(1) 或 WFI 循环 |
| C++ 静态初始化崩溃 | 时钟初始化前调用构造函数 | 先调用 SystemInit |
相关技能
skills/embedded/linker-scripts—_estack、LMA/VMA、段放置skills/baremetal/interrupts-and-exceptions-baremetal— 向量表中的 IRQ 条目skills/baremetal/bootloaders-embedded— 应用程序跳转时的 VTOR 重定位skills/embedded/openocd-jtag— 使用 GDB 在Reset_Handler处暂停skills/low-level-programming/assembly-arm— Thumb-2 语法skills/platform/riscv-privileged— RISC-V 陷阱设置
评论
支持 Markdown