baremetal-startup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBare-Metal Startup
裸机启动
Purpose
用途
Guide agents through bare-metal startup from reset to : reset and exception vectors, / initialization, stack and heap setup, C runtime integration with linker scripts, and common Cortex-M and RISC-V bring-up bugs.
main().data.bss指导Agent完成从复位到的裸机启动流程:复位与异常向量、/初始化、栈与堆设置、C运行时与链接脚本的集成,以及Cortex-M和RISC-V启动过程中的常见问题。
main().data.bssWhen to Use
使用场景
- Firmware hangs before reaching
main() - Porting to a new MCU without vendor HAL
- Writing custom or
startup.sReset_Handler - Integrating with
skills/embedded/linker-scripts - Debugging uninitialized globals or stack overflows at boot
- 固件在进入前挂起
main() - 移植到无厂商HAL的新MCU
- 编写自定义或
startup.sReset_Handler - 与集成
skills/embedded/linker-scripts - 调试启动时未初始化的全局变量或栈溢出
Workflow
工作流程
1. Boot sequence mental model
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)上电 / 复位
├── CPU 从vector[0]加载SP
├── CPU 从vector[1]跳转到Reset_Handler
├── Reset_Handler:初始化时钟(可选)、复制.data、清零.bss
├── 配置栈指针(若未从vector设置)
├── 调用SystemInit() / platform_init()
└── 调用main() —— 禁止返回(循环或WFI)2. Cortex-M vector table
2. Cortex-M向量表
On Cortex-M, the vector table starts at address 0 or a relocatable base (VTOR):
| Index | Entry |
|---|---|
| 0 | Initial stack pointer ( |
| 1 | |
| 2 | |
| 3 | |
| 4+ | IRQ handlers per NVIC |
asm
/* 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 .c
/* Linker symbols — declared extern in startup */
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;在Cortex-M中,向量表起始于地址0或可重定位基址(VTOR):
| 索引 | 条目 |
|---|---|
| 0 | 初始栈指针( |
| 1 | |
| 2 | |
| 3 | |
| 4+ | 对应NVIC的IRQ处理函数 |
asm
/* startup.s —— 极简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
/* ... 厂商CMSIS提供的设备IRQ向量 ... */
.section .text.Reset_Handler
.thumb_func
.global Reset_Handler
Reset_Handler:
ldr r0, =_sidata /* .data加载地址(LMA) */
ldr r1, =_sdata /* .data虚拟内存地址起始 */
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 .c
/* 链接器符号 —— 在启动代码中声明为extern */
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;3. VTOR relocation (Cortex-M)
3. VTOR重定位(Cortex-M)
c
#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., on STM32 flash).
0x08020000c
#include "core_cm4.h" /* CMSIS */
void relocate_vector_table(uint32_t base) {
SCB->VTOR = base & 0xFFFFFF80U; /* 必须符合ARM参考手册的对齐要求 */
__DSB();
__ISB();
}Bootloader跳转到应用程序时,通常需要将VTOR设置为应用程序的向量表地址(例如STM32闪存上的)。
0x080200004. RISC-V startup (overview)
4. RISC-V启动(概述)
asm
/* 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: for M-mode; see .
mtvecskills/platform/riscv-privilegedasm
/* entry.S —— 简化版 */
.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模式下使用;详见。
mtvecskills/platform/riscv-privileged5. crt0 responsibilities
5. crt0的职责
| Task | Who does it |
|---|---|
Copy | |
Zero | |
| Init stack | Vector[0] or explicit |
Heap ( | Optional; libc or custom |
| C++ constructors | |
| FPU enable | |
| 任务 | 执行者 |
|---|---|
复制 | |
清零 | |
| 初始化栈 | Vector[0]或显式设置 |
堆( | 可选;由libc或自定义实现 |
| C++构造函数 | 若使用完整libc则调用 |
| FPU使能 | Cortex-M4F/M7上由 |
6. Linker script integration
6. 链接脚本集成
ld
_estack = ORIGIN(RAM) + LENGTH(RAM);
_sidata = LOADADDR(.data);Cross-link for MEMORY/SECTIONS layout.
skills/embedded/linker-scriptsld
_estack = ORIGIN(RAM) + LENGTH(RAM);
_sidata = LOADADDR(.data);交叉参考获取MEMORY/SECTIONS布局。
skills/embedded/linker-scripts7. Agent usage examples
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?/baremetal-startup 我的STM32永远无法进入main——Reset_Handler应该做什么?
/baremetal-startup 引导加载程序跳转后,如何重定位向量表?Common Problems
常见问题
| Symptom | Cause | Fix |
|---|---|---|
| HardFault immediately | Stack pointer invalid | Set |
| Globals wrong at boot | | Copy LMA→VMA in Reset_Handler |
| BSS non-zero | | Add bss clear loop |
| IRQs don't fire | VTOR points to wrong table | |
| No loop after main | |
| C++ static init crash | Constructors before clocks | Call |
| 症状 | 原因 | 修复方案 |
|---|---|---|
| 立即触发HardFault | 栈指针无效 | 将 |
| 启动时全局变量值错误 | | 在Reset_Handler中实现从LMA到VMA的复制 |
| BSS非零 | | 添加BSS清零循环 |
| 中断无法触发 | VTOR指向错误的表 | |
| main后无循环 | 添加 |
| C++静态初始化崩溃 | 构造函数调用早于时钟初始化 | 先调用 |
Related Skills
相关技能
- —
skills/embedded/linker-scripts, LMA/VMA, section placement_estack - — vector table IRQ entries
skills/baremetal/interrupts-and-exceptions-baremetal - — VTOR relocation on app jump
skills/baremetal/bootloaders-embedded - — halt at
skills/embedded/openocd-jtagwith GDBReset_Handler - — Thumb-2 syntax
skills/low-level-programming/assembly-arm - — RISC-V trap setup
skills/platform/riscv-privileged
- ——
skills/embedded/linker-scripts、LMA/VMA、段布局_estack - —— 向量表中断条目
skills/baremetal/interrupts-and-exceptions-baremetal - —— 应用跳转时的VTOR重定位
skills/baremetal/bootloaders-embedded - —— 使用GDB在
skills/embedded/openocd-jtag处暂停Reset_Handler - —— Thumb-2语法
skills/low-level-programming/assembly-arm - —— RISC-V陷阱设置
skills/platform/riscv-privileged