この記事の前提
- Linuxが起動してログインできる状態は見たことがある方を想定します
- U-BootやDevice Treeの操作経験は不要です
- ボードごとの差を理解するための「共通の見取り図」を作る記事です
はじめに
第2部では、組み込みLinuxの起動の中身へ潜ります。今回は、電源を入れてからアプリケーションが動き出すまでに何が起きるかを一枚の地図にします。
起動トラブルは、「どの段階まで進んだか」が分かると調査範囲を大きく絞れます。前シリーズのA-1 層で切り分けるデバッグを、ブートに当てはめるイメージです。
ブートの共通シーケンス
実際の段数や名前はSoCとBSPによって異なりますが、学習用には次の6段階で整理できます。
- Boot ROM:起動元を決め、次の小さなプログラムを読み込む
- 初期ローダー:クロックやDRAMなど、後段に必要なハードウェアを初期化する
- ブートローダー:カーネル、Device Tree、起動引数を準備する
- Linuxカーネル:ドライバを初期化し、rootfsへ到達する
- PID 1/サービス:ユーザーランドとサービスを起動する
- 製品アプリ:装置固有の処理を開始する
SPL、TF-A、OP-TEE、UEFI、initramfsなどが途中に入る構成もあります。ここでは、それらを無理に省略するのではなく「どの役割の段階にいるか」で整理します。
1. Boot ROM:最初に動くコード
リセット解除後、SoC内のBoot ROMが動きます。起動モード端子、ヒューズ、SoC内部設定などを参照し、SD、eMMC、SPI NOR、USBといった候補から次段を探します。
探索順、格納位置、ヘッダー形式、署名検証の有無はSoCごとに異なります。この段階の約束を満たさないと、ストレージにファイルが存在していても次へ進みません。
Boot ROMは通常、製品開発者が書き換える領域ではありません。データシートやリファレンスマニュアルの「Boot」「System Boot」などの章が一次情報になります。
2. 初期ローダー:小さいメモリからDRAMへ
Boot ROMが使える内蔵SRAMは限られるため、小さなローダーがクロック、ピン、DRAMなどを初期化し、より大きなプログラムをロードできる状態を作ります。
U-Boot構成ではSPL(Secondary Program Loader)がこの役割を担うことがあります。ただしSPLは必須ではなく、TPL/VPL、ベンダー固有FSBL、Trusted Firmwareなど、構成によって名前も段数も変わります。U-Boot公式資料でも、TPL/VPL/SPLはオプションの段階として整理されています。
DRAM初期化に失敗すると、後段を展開できません。自作SoC基板では配線やパラメーター、既製ボードではボードリビジョンとBSPの組み合わせが確認点になります。
3. ブートローダー:カーネルの出発準備
Arm系の組み込みLinuxではU-Bootが広く使われています。典型的には次を行います。
- カーネルイメージをストレージやネットワークからDRAMへロードする
- Device Tree Blob(DTB)や必要なinitramfsを用意する
-
console=やroot=などのカーネルコマンドラインを渡す - カーネルのエントリーポイントへ制御を移す
U-Boot properには対話シェルがあり、printenvで環境変数を確認したり、ストレージやネットワークを調査したりできます。ただし、自動起動の中断方法や利用可能なコマンドはBSP設定に依存します。
Raspberry Piは世代で流れが違う
標準的なRaspberry Pi OSの構成では、通常U-Bootを使いません。また、Raspberry Piをひとまとめにしてbootcode.binとstart.elfで説明すると、現行世代では不正確です。
- Pi 3以前を中心とする旧世代:Boot ROMがブート領域の
bootcode.binなどを使う構成 - Pi 4、Pi 400、CM4以降:オンボードSPI EEPROMのブートローダーを使用
- Pi 5:EEPROM内のブートローダーがLinuxカーネルをロードし、
start.elfは使用しない
詳しい世代差はRaspberry Pi公式のEEPROM boot flowで確認できます。config.txtはハードウェアやカーネルロードに関する設定を持ちますが、U-Boot環境変数と完全に同じものではありません。
4. Linuxカーネル:rootfsへ到達する
カーネルはCPU、メモリ管理、割り込み、タイマー、各種デバイスを初期化します。Device Treeは、基板上にどのデバイスがあり、どのアドレス、割り込み、GPIO、クロックへ接続されているかをカーネルへ伝えます。
その後、カーネルコマンドラインのroot=などをもとにrootfsをマウントします。構成によっては、先にinitramfs上の初期ユーザーランドを動かしてから、本来のrootfsへ切り替えます。
代表的な停止例が次のメッセージです。
VFS: Unable to mount root fs on unknown-block(...)
root=の指定、ストレージドライバ、ファイルシステムドライバ、パーティション、rootfs破損などを確認します。メッセージ前後の情報が重要なので、一行だけで判断しません。
5. PID 1:ユーザーランドを立ち上げる
rootfsへ到達すると、カーネルは最初のユーザープロセスを起動します。このプロセスがPID 1です。Raspberry Pi OSなどではsystemdが一般的ですが、BusyBox initや独自initを使う製品もあります。
この段階では、ファイルシステムのマウント、ネットワーク、デーモン、製品アプリなどが依存関係に従って起動します。カーネルログが正常でもアプリが動かない場合は、systemctlやjournalctlなど、ユーザーランド側の観測へ切り替えます。
症状から停止段階を絞る
| 見えている症状 | 候補となる段階 | 最初に確認するもの |
|---|---|---|
| 電源を入れても反応がない | 電源、リセット、Boot ROM以前 | 電源レール、リセット、起動モード、LED仕様 |
| UARTに何も出ない | UART設定またはBoot ROM〜初期ローダー | 電圧、TX/RX、ボーレート、ピンmux、ブートメディア |
| SPL/FSBL付近で停止 | 初期化、DRAM、次段ロード | 対応イメージ、基板リビジョン、DRAM設定 |
| U-Bootプロンプトまで出る | カーネル/DTBロード |
printenv、ストレージ認識、ファイル名 |
Starting kernel ...後に沈黙 |
console設定またはカーネル初期 |
console=、UARTドライバ、DTB |
VFS: Unable to mount root fs |
rootfs到達 |
root=、ドライバ、パーティション、rootfs |
| 起動ログは完走するがアプリが動かない | PID 1/サービス | unit状態、依存関係、アプリログ |
UARTに何も出ない場合でも、Boot ROMで止まったとは限りません。UARTが有効になる段階、出力先、ピンmux、セキュア設定によって、正常起動中でも無表示になることがあります。LEDコード、HDMI診断、ネットワーク応答、消費電流など、別の観測手段と組み合わせます。
ハマりどころ
- 正常ログを先に保存する:異常時だけ見ても境界が分かりません。同じハード・同じイメージの正常ログを基準にします
-
console=の出力先を確認する:カーネルは動いていても、ログが別UARTや画面へ出ている場合があります - ログは接続前から保存する:ターミナルを開いてからリセットし、先頭を取り逃さないようにします
- ファイル名だけで役割を決めつけない:ベンダーBSPでは複数のファームウェアがまとめられていたり、署名コンテナに格納されたりします
- 同じSoCでもイメージを流用しない:DRAM、PMIC、PHY、Device Treeなどのボード差分があります
現場コラム:ブートチェーンを図にする
新しいボードを扱うときは、「誰が、どのストレージの、どのバイナリを、どこへロードするか」を図にします。
| 段階 | 確認すること |
|---|---|
| Boot ROM | 起動モード、探索順、署名条件 |
| 初期ローダー | ファイル名、格納位置、DRAM初期化 |
| ブートローダー | カーネル、DTB、initramfs、bootargs |
| カーネル | rootfs指定、必要ドライバ |
| PID 1 | 製品アプリの起動条件 |
この表が埋まると、書き込みツールの意味、復旧手順、A/B更新、セキュアブートの議論も追いやすくなります。「動くイメージ」を保管するだけでなく、構成要素と生成元を記録することが重要です。
起動済みLinuxから答え合わせする
手元のボードで次を実行し、カーネルへ渡された起動引数を確認してみてください。
cat /proc/cmdline
console=とroot=を探し、どこへログを出し、どのrootfsを使っているかを読みます。表示内容はボードとOS構成によって異なります。
まとめと次回
- ブートを「Boot ROM→初期ローダー→ブートローダー→カーネル→PID 1→アプリ」の役割で整理する
- SPLやU-Bootはよく使われるが必須ではなく、SoCとBSPによって段数や名前が変わる
- 症状と観測手段を対応させ、最後に確認できた境界から調査する
- Raspberry Piも世代により
bootcode.bin、EEPROM、start.elfの扱いが異なる
次回C-6では、この地図を使ってシリアルコンソールへ出る典型的なブートログを段階別に読み解きます。掲載ログは読み方を説明するための抜粋例とし、実機で取得した値のようには扱いません。
A-2 シリアルコンソール編も、接続とログ保存の予習として参照できます。
