Android は、スケジューリング、プロセス分離、デバイスドライバー、ネットワーク機能、ファイルシステムに Linux カーネルを使用しますが、独自のネイティブライブラリ、ランタイム、フレームワーク、アプリケーションモデルを提供します。Bionic は Android の C ライブラリです。ART は DEX バイトコードを実行し、Binder は主要なプロセス間 RPC 機構を提供します。
ランタイムとプロセス生成 #
ビルドツールは Java または Kotlin のソースをクラスファイルにコンパイルし、その後 DEX コードに変換します。APK またはアプリバンドルの配信分割では、DEX、リソース、ネイティブライブラリ、署名メタデータ、マニフェストがパッケージ化されます。ART はデバイスとプロファイルの状態に応じて DEX をコンパイルまたはインタープリットします。そのため、APK は単純な実行可能 JAR ではありません。
init は Android の PID 1 プロセスです。初期ファイルシステムをマウントし、ポリシーを適用し、ネイティブサービスを起動して、Zygote を起動します。Zygote は共通のランタイムクラスとリソースを事前ロードし、システムから要求されるとアプリケーションプロセスを fork します。fork モデルでは、いずれかのプロセスがページを書き込むまでページを共有するため、アプリケーションの起動コストを削減できます。
アプリケーションの分離と Binder #
パッケージのインストール時には、通常、個別の Linux UID が割り当てられます。ファイル所有権とカーネル認証情報によってアプリ専用ファイルが分離され、SELinux はプロセス、ファイル、サービス、Binder 呼び出しに強制アクセス制御ポリシーを適用します。カーネル制御に加えて、フレームワークおよびサービスの境界でも権限が検査されます。
別のパッケージで起動されたアプリコンポーネントは、対象パッケージのプロセスで実行されます。Binder はトランザクションをそのプロセスへ転送し、権限チェックのために呼び出し元の識別情報を伝達します。Binder オブジェクト参照は、ライフサイクルと権限に関するセマンティクスを持つケイパビリティです。エクスポートされたコンポーネントまたはサービスは、呼び出し元が制御するすべての引数を検証する必要があります。
システムパーティションと更新 #
現代のデバイスでは、オペレーティングシステムイメージを通常、論理的で原則として読み取り専用のパーティションに分割します。
| Mount | Purpose |
|---|---|
/system | コアフレームワーク、ランタイム、プラットフォームアプリケーション |
/system_ext | プラットフォーム固有のライフサイクルを持つシステム拡張 |
/product | 製品および OEM によるカスタマイズ |
/vendor | ハードウェアベンダーのライブラリ、HAL、設定 |
/odm | デバイス固有のベンダーオーバーレイと設定 |
/vendor_dlkm, /system_dlkm | 動的にロード可能なカーネルモジュール |
/data | デバイスおよびユーザーごとの書き込み可能なアプリケーションデータ |
/metadata | 暗号化およびブートサービスに必要なメタデータ |
動的パーティションでは、論理パーティションを物理的な super パーティション内に配置します。dm-5 などの Device-mapper 名は、それらの論理ブロックデバイスを表します。ほぼ満杯の容量を報告する読み取り専用イメージは、通常、不変のファイルシステムイメージであり、ユーザーデータストレージが枯渇したことを示すものではありません。
Verified Boot は、ブートおよび検証済みパーティションに対する信頼の連鎖を確立します。A/B 更新では、非アクティブなスロットに書き込み、検証後にそのスロットを選択します。これにより、新しいスロットが起動に失敗した場合にロールバックできます。
APEX とネイティブインターフェイス #
APEX パッケージは、ART や Conscrypt など、選択された低レベルのプラットフォームモジュールを配信します。Android はブートの早い段階で APEX イメージを検証して /apex 以下にマウントし、安定したパスによってアクティブなバージョンを公開します。ベンダーインターフェイスとハードウェア抽象化レイヤーは、特定の Android リリースに適用される互換性規則に従い、フレームワークのリリースとベンダー実装を分離します。
書き込み可能なストレージとマウント名前空間 #
/data は主要な書き込み可能パーティションです。ファイルベース暗号化では、ユーザーのロック解除前から利用可能なデバイス暗号化ストレージと、ロック解除後に利用可能な認証情報暗号化ストレージを区別します。ユーザー単位のパスには /data/user/0 と /data/user_de/0 があります。
エミュレートされた共有ストレージは /storage/emulated/0 などのパスで公開され、/data/media 以下のプライベートストレージを基盤とします。FUSE とマウント名前空間によって、各アプリケーションとユーザーに適切なビューが提供され、スコープ付きストレージのアクセス規則が適用されます。/storage/self/primary はプロセスのプライマリ共有ストレージビューに解決されます。コードでは、実装パスをハードコードせず、プラットフォームのストレージ API を使用する必要があります。
proc、sysfs、binderfs、selinuxfs、cgroupfs、tracefs などの疑似ファイルシステムは、永続ファイルではなくカーネルインターフェイスを公開します。mount の一覧はデバイス、リリース、プロセス名前空間に固有であるため、移植可能なファイルシステム契約ではなく、診断上の証拠として扱う必要があります。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)