Edited at

Raspberry Pi2(Linux Kernel)のブートシーケンスを読む(その1) アーキテクチャ依存部

More than 3 years have passed since last update.


目的

Raspberry Pi2のブートシーケンスを調査する事によって、

Linux Kernelのブートプロセスを学びます。

同時に、Linux Kernel内部で使用される各種構造体の役割を理解します。


使用機器・ソースコード

・Raspberry Pi2 ModelBおよび周辺機器

Raspberry Pi(OS)のソースコード rpi-4.1.y

・MacBook Air


電源投入からKernelに制御が移行するまで

今回の目的は、「Kernelを知る事」であり、ブートローダなどの役割を知る事ではありません。

そのため、概略だけを記載します(検証をしていないため、誤っている可能性があります)。

 Kernelに制御が移行するまで

  1)電源を投入

  2)GPU(Broadcom VideoCore IV)が起動

  3)GPUがSoCのROMからBootloader(名称不明)を読み込み、実行

  4)GPUがmicroSDをマウント

  5)GPUがmicroSDからL2キャッシュにbootcode.binを読み込み、実行

  6)bootcode.bin内でloader.binをmicroSDカードからRAMへ読み込み、実行

  7)loader.bin内でGPU firmware(start.elf)を読み込む

  8)start.elf内でconfig.txt、cmdline.txtとkernel.imgを読み込む

   kernel.imgの展開先は0x8000です。

   (この3つのファイルは/bootにあります。また、start.elfはGPU binary)

  9)start.elf内でconfig.txtの内容に従い、ファイルを読み込む

  10)start.elf内でCPUを起動し、KernelのStart Addressに移動

    (ここから、Kernel内部のコードを処理する事になる)


疑問点

1.ARMに関わらず、一般的に多段ブートを行う(複数のBootloaderを使用する)理由

過去のシステムと互換性を保つために、多段ブートを採用しています。

多段ブートに関して押さえておきたい点は、以下の通りです。

 ・(Intel x86系では)BIOSがリアルモードで動作する事

 ・現代のBootloaderのサイズが、BIOSのロード可能サイズを超えている事

まず、リアルモードとは16bit動作モードで、

一度にアクセスできるデータサイズは64KB、メモリ空間は1MBです。

前述したように、BIOSがリアルモードで動作するため、

このリアルモードからプロテクトモード(32bit)やロングモード(64bit)に、

CPUのモードを切り替える作業が必要になります。

この作業により、Bootloaderの中身が複雑になります(サイズが大きくなります)。

次に、Bootloaderのサイズが大きい事についてです。

サイズが大きくなる原因は、最近のBootloaderに以下のような機能が加わっているからです。

 ・ブート可能なKernelのリストを表示

 ・Kernelオプションの指定(編集機能)

 ・ファイルシステムから指定のファイルの読み込み

このような機能は、BIOSが読み込めるサイズ(512byte)で実現できません。

この問題を解決するために、多段ブートという手法が生まれました。

BIOS>1段目Bootloader(リアルモード、512Byte)>2段目Bootloader(プロテクトモード)>・・・

    

 

2.CPUではなく、GPUがブート処理を行う理由

ブートコードを隠蔽するため(らしい)。

何故、ブートコードを隠蔽する必要があるのか、という新しい疑問が生まれましたが、

本筋と大幅にズレるため、解決を保留します。


次回

「Raspberry Pi2(Linux Kernel)のブートシーケンスを読む(その2)」

Kernel内のENTRY(stext)でCPU IDを取得するまでの説明を記述しています。


参考サイト

第2回北陸ARMU.G.勉強会「Raspberry Piのブートシーケンスについて」

OSdev

Raspberry Piのブートプロセスメモ

Raspberry PI bare metal Part 1: The Boot Process