baremetal-startup について
リセットからmain()までのベアメタル起動を扱うエージェント向けスキルです。Cortex-MとRISC-Vのベクターテーブル、メモリー初期化、リンカースクリプト連携、起動時の障害を解説します。
主な機能
- 01リセットハンドラーとベクターテーブルの設定
- 02.dataと.bssの初期化
- 03Cortex-MのVTOR再配置
- 04RISC-V起動の概要
- 05リンカースクリプトとの連携
- 06起動障害の診断
活用シーン
- 01main()に到達しないファームウェアの調査
- 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を入力して読み込まれたか確認します。
詳細
ベアメタルの起動
目的
リセットから 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 モードでは 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);
MEMORY/SECTIONS のレイアウトについては、skills/embedded/linker-scripts と相互参照してください。
7. エージェントの使用例
/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 対応