mcpField
B
baremetal-startup

baremetal-startup

github.com/mohitmishra786开发269310 次安装18 周前更新
代码仓库

关于 baremetal-startup

面向从复位到 main() 的裸机启动开发 Agent,涵盖 Cortex-M 和 RISC-V。内容包括向量表、内存初始化、链接脚本集成及常见启动故障。

主要功能

  1. 01复位处理程序与向量表配置
  2. 02.data 和 .bss 初始化
  3. 03Cortex-M VTOR 重定位
  4. 04RISC-V 启动概览
  5. 05链接脚本集成
  6. 06启动故障诊断

适用场景

  1. 01排查固件无法到达 main()
  2. 02为没有厂商 HAL 的 MCU 移植
  3. 03编写自定义 startup.s 或 Reset_Handler
  4. 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)
1Reset_Handler
2NMI_Handler
3HardFault_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 复制到 VMAReset_Handler / crt0
将 .bss 清零Reset_Handler
初始化栈Vector[0] 或显式设置 sp
堆(_sbrk)可选;由 libc 或自定义代码提供
C++ 构造函数使用完整 libc 时调用 __libc_init_array()
启用 FPUCortex-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