スタートアップコードとは?データ領域とBSS領域はどのように初期化されるのか

目次

スタートアップコードとは?(概要)

スタートアップコードとは、main() が呼ばれる前に実行される初期化コードです。

スタートアップコードは、

  • スタックポインタ初期化
  • データ領域のコピー
  • BSS領域のゼロクリア
  • main() 呼び出し

を行います。

データ領域とBSS領域についてはこちらの記事で解説しています。

スタック領域についてはこちらの記事で解説しています。

メモリ領域解説シリーズ

本記事は「メモリ領域解説」シリーズの1つです。

メモリ領域解説シリーズの全体像はこちら

マイコンの電源を入れた瞬間、C言語の main() がすぐに実行されるわけではありません。

その前に必ず実行されるのが「スタートアップコード」です。

この記事では、

  • スタートアップコードとは何か
  • データ領域はどう初期化されるのか
  • BSS領域はなぜゼロになるのか
  • 実務でどこを確認すべきか

を解説します。

初心者さん

スタートアップコードって、mainの前に動くコードってことですか?

エンジニアくん

そう。C言語が動く前に、実行環境を整えるコードなんだ。

初心者さん

でも、グローバル変数って最初から初期化されてるんじゃないんですか?

エンジニアくん

それはスタートアップコードが初期化しているからなんだよ。
電源投入直後のRAMは中身が保証されていないからね。

初心者さん

じゃあ、スタートアップコードがないとどうなるんですか?

エンジニアくん

データ領域の初期値は反映されないし、
BSS領域もゼロにならない。
つまりグローバル変数が全部ゴミ値になる。

初心者さん

それは危険ですね…

エンジニアくん

だから組み込み開発では、
スタートアップコードはかなり重要な処理なんだ。

このようにスタートアップコードはメモリ領域に深くかかわるコードになります。

データ領域、BSS領域、スタック領域を含むメモリ領域の全体像についてはこちらの記事で解説しています。


マイコン起動直後の状態

電源投入直後のRAMは保証されていません。

データ領域 → 不定値
BSS領域 → 不定値(後で0初期化される)
スタック → 初期化されていない

このままではC言語は正しく動作しません。


スタートアップコードが行う処理

一般的に次の処理を行います。

① スタックポインタ初期化

リンカスクリプトで定義されたアドレスに設定します。


② データ領域のコピー

ROMに保存された初期値を、
RAMのデータ領域へコピーします。

ROM (.data初期値)
      ↓ コピー
RAM (.data実体)

③ BSS領域のゼロクリア

BSS領域全体を0で初期化します。

memset(&__bss_start__, 0, size);

④ main() 呼び出し

ここで初めてCコードが動きます。

⑤ データ領域/BSS領域 の範囲定義

スタートアップコードは、
どこからどこまでを初期化するかを
リンカスクリプトで定義されたシンボルを使って決定します。

例えば次のようなシンボルです。

__data_start__
__data_end__
__bss_start__
__bss_end__

スタートアップコードはこれらのアドレスを使い、

データ領域をコピー
BSS領域をゼロクリア

という処理を行います。

例えば BSS 初期化は次のようになります。

memset(__bss_start__, 0, __bss_end__ - __bss_start__);

この範囲が間違っていると、

初期化されない変数が出る
別領域を破壊する
起動時にクラッシュする

といった問題が発生します。

そのため、ブートローダを導入した場合や、
メモリ配置を変更した場合は、
この範囲定義を必ず確認する必要があります。

スタートアップコードが行う処理まとめ

まとめるとこのように処理が進みます。

Reset
 ↓
startup
 ↓
stack初期化
 ↓
.dataコピー
 ↓
.bssクリア
 ↓
main()

なぜこれが重要なのか?

もしスタートアップコードが正しく動かなければ、

  • 初期値が反映されない
  • グローバル変数がゴミ値
  • 予期しない暴走

が起きます。

組み込みで「たまに起きる不具合」は、
ここが原因のこともあります。


実務で確認すべきポイント

  • マップファイルでdata/bssサイズ確認
  • リンカスクリプトで配置確認
  • スタートアップコードのコピー範囲確認

特に独自ブートローダ環境では要注意です。


まとめ

データ領域とBSS領域は、
スタートアップコードによって初期化されます。

この流れを理解すると、

  • メモリ不足の原因追跡
  • 初期化バグの切り分け
  • 起動時間最適化

ができるようになります。

この記事が参考になった方へ

メモリ領域については他の記事でも解説しています。

メモリ領域解説シリーズの全体像はこちら

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

お問い合わせはこちら

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする


目次