ディストリビューション:ブートプロセスガイド - asfdrwe/asahi-linux-translations GitHub Wiki
2023/8/12時点のDistro:Boot process guideの翻訳
このページでは、起動可能な Asahi Linux システムに含まれるパッケージ/コンポーネントと、それらがどのように相互作用するかを説明します。 ディストリビューションのパッケージ担当者や、パッケージを使う代わりに自分でビルドを開発・管理したい人を対象にしています。Arch Linux ARM ベースのリファレンスディストリビューションで使われているセットアップをベースにしていますが、ほとんどのシステムに適用できるはずです。
これは実用的なガイドです。ベンダーのファームウェアの扱い方を含む、より正式な説明や仕様については Apple Silicon MacでのオープンOSエコシステム を 参照してください。私たちの Arch Linux ベースのリファレンスディストリビューションにどのように組み込まれるのかについては ディストリビューション:Arch Linux ARMとの違い を見て下さい。
[Appleによる部分] → m1n1 第1段階 → m1n1 第2段階 → DT(訳注:DeviceTree) + U-Boot → GRUB → Linux
m1n1 第1段階 は Asahi Linux インストーラによってリカバリーモードからインストールされ (step2.sh 内)、その過程で内部マシン固有の鍵に
よって署名され (Apple のセキュアブートポリシーの一部として)、不変と見なすことができます。アップグレードはめったに必要ないはずですが、
必要になればそのためのツールを作る予定です。この OS に割り当てられた EFI システムパーティションの PARTUUID をハードコードし(インストール時に設定)、
<ESP>/m1n1/boot.bin
から m1n1 ステージ 2 をチェーンロードします(ESP は内部 NVMe ストレージでなければならず、外部ストレージには
対応してしません)。また、この PARTUUID を次のステージに渡すので(設定する/選択するプロパティとして、以下を参照)、次のステージは、
どのパーティションから起動しているかが分かります。
OS/ディストリビューションは、残りのブートコンポーネントの保守とアップグレードを担当します。
m1n1 第2段階は、(さらに)ハードウェアの初期化、このプラットフォームに適した DT の選択、動的プロパティの記入、および U-Boot の読み込みを担当します。
U-Boot はより多くのもの(キーボードや USB など)を初期化し、UEFI サービスを提供し、(デフォルトでは、私たちのリリース設定において)、マジックに則って
<ESP>/EFI/BOOT/BOOTAA64.EFI
から UEFI バイナリをロードします。U-Boot は DT を消費し、少し修正し*、転送することに注意してください。
GRUBはバニラで、特別なことは何もありません。他のarm64 EFIバイナリも使用可能です。
- 大きくは、物理/キーボードコンソールかUARTコンソールかのどちらかを使っているかを判断して、stdout-pathを設定するのみです。
Asahiでは、OSごとにEFIシステムパーティションを設定するという非標準的な設定を行っています。AppleのブートピッカーはEFIについて何も知らないので、 この方が適合しやすいのです。Appleの観点では、インストールされたAsahiインスタンスはそれぞれ別のOSであり、それゆえ下流ではそれぞれ別のESPを 使用するのです。複数のブートローダやOSを1つのコンテナ/ESPにインストールすることを止めることはできませんが、以下のような問題があります。
- セキュリティ関連のプラットフォーム機能(例:SEP)との統合を開始すると、『現在起動しているOSのID』という概念を持つ可能性があるため、将来的に苦痛をもたらすと疑念
- DT、U-Boot、m1n1 stage2 version はコンテナ/ESPごとに1セットしか存在できないため、複数のディストリビューションが1つのコンテナを共有する場合、アップデート管理のために協力するまともな方法なし
- 永続的な EFI 変数ストレージがないので(ランタイムサービスでそれを行う方法の良いアイデアもなし)、EFI の起動順序を管理する方法なし。そのため、結局はデフォルトのものしかない
したがって、もしエンドユーザー向けにディストリビューション対応を追加するのであれば、このモデルにこだわってください。例外は USB で起動する
レスキュー/インストーライメージで、Asahi Linux インストーラがプレーンな UEFI コンテナモードでインストールするバニラm1n1.bin バンドルに
よって起動できる必要があり、 /EFI/BOOT/BOOTAA64.EFI
(m1n1/boot.bin
なし) を含む USB ドライブの独自の ESP から起動できるようにする
必要があります。これらは決して内部の ESP で boot.bin
を管理しようとしないでください (正しくインストールされるまで、あるいは
インストールされない限り、そのコンテナのオーナーになります)、USB ブートでは DT の状況がうまくいくことを期待します。
現在起動している OS に割り当てられている EFI システムパーティションの PARTUUID は、m1n1 によって /chosen
DeviceTreeノードの asahi,efi-system-partition
プロパティとして設定され、Linux から /proc/device-tree/chosen/asahi,efi-system-partition
で読むことができるように
なっています。私たちのU-Boot ブランチもこれを使って正しい ESP を探します。
m1n1、u-boot、Linux、そしてDeviceTreeには、やや複雑で微妙なバージョンの相互依存性があります。
- m1n1 第2段階 は、いくつかのハードウェアの初期化、およびデバイスツリーへの動的な値のパッチを担当。つまり、新しいカーネルハードウェア対応は、頻繁に m1n1 の更新に依存し、初期化するか、DeviceTreeのデータを追加するか、あるいはその両方実行
- 一般に、Linuxドライバをシンプルに保ち、『魔法の』init(例えば、Appleが彼らのDTの変種で表現するのが好きな、レジスタ書き込みのランダムな魔法のセット)をm1n1に置くことを好む。メモリコントローラに関連するもの、静的にしておくのが妥当なクロックコンフィギュレーションなども同じ。例外は、Linux が実行時に動的にこれを行うしかない場合。AppleはXNUカーネル(m1n1が置き換える)にあまりに多くのことを任せるのが好きで、システムレベルのL3キャッシュをオンにするような馬鹿げたことを含みますが、Linuxがそれに対処する必要はなし。これはまた、既存のカーネルが DT の変更だけで新しい SoC/プラットフォームで(少なくとも部分的に)動作する可能性を非常に高めるものであり、例えばdディストリビューションのインストールイメージの前方互換性にとって良い。例えば、M2 の PCIe はドライバレベルの変更は必要なく、m1n1 の初期化のみの変更でOKだと
- U-Boot は一般に、任意の SoC で適切に起動した後はあまり変更せず、DT 情報のサブセットを気にする程度
- Linux はハードウェアを起動するために DT データを必要とするので、新しいハードウェアには DT の更新が必要。私たちの標準的なDTリポジトリは、Linuxツリーの一部ですが、ここでの変更は、実際に動作させるために頻繁にm1n1(ステージ2)アップデートを必要とすることを覚えておくべき
すべてが上流にあり、すべてのハードウェアを理解している理想的な世界では、DTはソフトウェアのバージョンと前方および後方互換性があるべきです。 つまり、新しい機能はすべてを最新にする必要がありますが、そうでなければ、その新機能は単に利用できなくなるだけです。
現実の世界では、
- まだ上流に統合されていないDTバインディングは、レビューを通過する際に互換性のない変更が行われることあり。私たちはこれを避けようとしていますが、実際には発生 (例えば、AIC2 IRQ コントローラバインディングが変更され、特に t600x の古いカーネルでは完全に起動が不能に)。互換性を維持するために、両方のスタイルのデータを持つ暫定的なDTを保持
- m1n1 は、パッチを当てたい変更に対して DT 構造が欠けている場合 (つまり m1n1 バージョン > DT バージョン) には優雅に劣化するはずですが、これらのコードパスはあまりテストされていない。もし、中止したり、クラッシュしないはずなのにクラッシュするのを見たら、バグ報告してください
- 任意の SoC での U-Boot の初期には、DT の依存関係に変更があるかも (たとえば、M2 プラットフォームの MTP キーボードサポートは DT の変更に伴って行われますが、これは欠落すると優雅に劣化)
- 原則的に、m1n1 がハードウェアを適切に初期化するために更新されなかった場合、Linux ドライバがひどくクラッシュする可能性があり(そして、DT props を注入していない場合、 ドライバがそれらを欠落しているために失敗することはない)。私たちは明らかにエラーを優雅に扱おうとしますが、例えば電源やメモリコントローラ関連のinitが見つからないと、Linuxが依存するハードウェアを立ち上げようとしたときに、SoCウェッジが固まるようなことが起こる可能性あり。DTにm1n1バージョンを詰め込んで、古いバージョンで何か安全でないことが知られている場合に、ドライバが救済できるようにすべき?
- DT の変更には、『完全な互換性』という理想に反して、修正するのがあまり簡単でないコーナーケースあり。例えば、DTノードが他のノードへの依存関係(例えば、プロデューサーと消費者の関係)を導入する場合、それが原則的にオプションであったとしても、プロデューサーのドライバーが利用できない、プローブできない、または適切なプロデューサー機能を実装しない場合、そのドライバーはプローブできない(またはプローブしようとしない)かも。また、パワードメインに関する問題もあり。現在、いくつかのパワードメインは、オフにすると何かひどく壊れてしまうため、『常時オン』とマークされているが、将来的には、これを適切に処理する方法を学ぶことができるかも。新しいDTでこのフラグが削除されると、古いカーネルは困るはず
複数のカーネルをインストールすることは 可能 ですので、DTのソースとなる場所をどうにかして選ばなければなりません。論理的には最新のカーネルを選択することになります。Arch では、標準パッケージでインストールされるカーネルは1つだけなので、 (一般的なユーザーにとっては)この問題を無視して、パッケージのアップデート時に 常にそのバージョンの DT をアップデートするようにしています。
TL;DR: カーネルをアップデートするときは DT をアップデートしてください(触られていないことが分かっている場合を除く)。 また、大きな新しいものを動作させるためにm1n1もアップデートしてください。
全てがネイティブで行われると仮定します(クロスコンパイルなし)。
git clone --recursive https://github.com/AsahiLinux/m1n1
cd m1n1
ARCH= RELEASE=1
注: RELEASE=1 は現在、デフォルトで冗長なログ出力をオフにするだけです。リリースビルドでは、recoveryOSから nvram boot-args=-v
を使って有効にできます。
出力は build/m1n1.bin
にあります。
git clone https://github.com/AsahiLinux/u-boot
cd u-boot
git checkout asahi-releng # このブランチはユーザに出荷するもので、EFIパーティションの自動検出機能がついています。
make apple_m1_defconfig
make
出力は u-boot-nodtb.bin
にあります。
標準的なDTは、私たちのLinuxカーネルツリーにあるものです。カーネルをビルドするのはこのドキュメントの範囲外です。
出力は arch/arm64/boot/dts/apple/*.dtb
にあります。
m1n1、デバイスツリーのセット、U-Bootは全て一つのファイルにまとめられ、m1n1 stage 2となり、 <ESP>/m1n1/boot.bin
から読み込まれます。これは、update-m1n1スクリプトを使用して、単純に連結することで行われます。
簡略化すると
m1n1_dir="/boot/efi/m1n1"
src=/usr/lib/asahi-boot/
target="$m1n1_dir/boot.bin"
dtbs=/lib/modules/*-ARCH/dtbs/*
cat "$src/m1n1.bin" \
$dtbs \
<(gzip -c "$src/u-boot-nodtb.bin") \
>"${target}"
注意事項
- U-boot を m1n1 で確実に読み込むには gzip する必要あり (これはイメージフォーマットがセルフデリミティッドでないことに関係)
- m1n1は与えられたプラットフォームに対して適切なデバイスツリーを選択
- Asahi Linux カーネルパッケージは DTB を
/lib/modules/$ver/dtbs/
にインストール。これは非標準 - .bin にテキスト形式の
var=valuen
行を追加して、m1n1 でいくつかの設定をすることが可能。将来的には、このためのより良いツールを用意する予定ですが、今のところ、非常に特殊なケースにのみ使用
アップデート後に古い m1n1.bin
をリネームしておくとよいでしょう。macOS は FAT32 ESP に問題なくアクセスできるので (diskutil list
して diskutil mount
でマウントします)、起動に失敗したら macOS かリカバリーモードに入って古いものを戻せばいいだけです。
m1n1 は Apple のキーボードコードを /proc/device-tree/chosen/asahi,kblang-code
に詰め込んでいます (ビッグエンディアンの
u32 cellで、DT の標準)。マッピングは ここに
あります。これに対する適切なバインディングを標準化する方法については、自由にディスカッションを開始してください。
ベンダーファームウェア(すなわち、ディストリビューションのパッケージとして再配布できないが、インストール時に準備されるファームウェア)が どのように扱われるかについて、私たちは全体のストーリーをもっています。それがどのように機能するかは、こちら で詳しく解説されています