Posted at

Linux/arm64のブートプロセスについてのメモ

More than 3 years have passed since last update.

Linuxのブートプロセスを追うときに見るべきファイル(x86_64編)のarm64版のようなもの。


ブートストラップ

linux/Documentation/arm64/booting.txt によると、現在のarm64用カーネルは、x86_64用カーネルが持つようなブートストラップの機能が存在しない。実際、arch/arm64/boot/以下にはx86_64のようなソースコード(head_64.S等)が存在しない。ブートローダがハードウェアの最低限の初期化をして、解凍された生のカーネルイメージ(ELFではない)を配置、エントリポイントにジャンプしてやらないといけない。カーネルに実行を移すときの要件も、booting.txtに書かれている。

ブートローダとしては、ubootやUEFIが使えると思われる。(Boot Wrapperというのも使えるみたいだが、今も使えるかは分からない。)


ブートプロセス


  • arch/arm64/kernel/head.S


    • エントリポイントは_text

    • _textは.head.textセクションの先頭にある


      • .head.textセクションはファイル先頭の__HEAD



    • すぐにstextへジャンプ

    • いろいろ初期化


      • ブート引数を待避

      • EL2(ハイパーバイザ用の実行モード)からEL1へ落ちる


        • eret命令



      • __boot_cpu_modeにブートしたときのCPUモードを設定する

      • ページテーブルを設定



    • 最終的に__cpu_setupへジャンプする


      • 戻ってくるアドレスを__enable_mmuにしておく

      • 後で使うために、x27に__mmap_switchedのアドレスを入れておく





  • arch/arm64/mm/proc.S


    • __cpu_setupがある

    • MMUをonにするためのCPUの初期化


      • SCTLRとかTCRとかTTBRの値を用意する



    • 最後にretすると__enable_mmuに飛ぶ



  • arch/arm64/kernel/head.S


    • __enable_mmuでTTBR0とTTBR1を設定

    • SCTLRを設定する

    • x27レジスタを使って__mmap_switchedに飛ぶ

    • start_kernelに飛ぶ



  • init/main.c


    • start_kernelがある




Imageのファイル形式

ところで、CONFIG_EFIがyesの場合、自分でビルドしたカーネル(Image)をfileコマンドで見てみると、"MS-DOS executable, MZ for MS-DOS"と判定される。これは、(U)EFIがPE形式(MS-DOS MZ)を必要としているためらしい。そのため、MZヘッダのふりをするために(ファイル先頭が0x5A4Dになるように)、命令の先頭は"add x13, x18, #0x16"という意味のない命令になっている。あと_textの直後(stextの手前)にPEヘッダが用意されている。

そういえばx86_64の方でもarch/x86/boot/header.Sの先頭にそれらしきものがあった気がする。


参考文献