Androidのリカバリシステム (Androidのシステムアップデート)

55
Android のリカバリシステム (Android のシステムアップデート ) 横浜 Android and モバイル OS プラットフォーム部 第 37 回勉強会 2015/2/22 @l_b__
  • Upload

    lb
  • Category

    Software

  • view

    3.117
  • download

    3

Transcript of Androidのリカバリシステム (Androidのシステムアップデート)

Page 1: Androidのリカバリシステム (Androidのシステムアップデート)

Android のリカバリシステム(Android のシステムアップデート )

横浜 Android and モバイル OSプラットフォーム部

第 37 回勉強会

2015/2/22@l_b__

Page 2: Androidのリカバリシステム (Androidのシステムアップデート)

今日の内容

● ABS2012 の Intel Andrew Boie 氏のセッション、“ Android Software Updates” をベースに Android の OTA アップデート / リカバリシステムの解説をします

● Lollipop で の 新 機 能 、 SecureBoot/Block- Oriented OTA についても少々

Page 3: Androidのリカバリシステム (Androidのシステムアップデート)

自己紹介

● Twitter ID:@l_b__ ● PF 部の司会進行役 兼 懇親会手配役 兼 配信

係 兼 雑用係● フレームワーク周りが好物です● BeOS 好きだったのと Java-er なので Be 関係者

が多い ( 多かった )Android に惹かれました● 仕事は某 SIer で Android フレームワーク修正か

らアプリ作成までやっていましたが最近はAndroid やっていません

Page 4: Androidのリカバリシステム (Androidのシステムアップデート)

Android リカバリシステムの概要

Page 5: Androidのリカバリシステム (Androidのシステムアップデート)

OTA アップデートの手順OS ビルド・ OTA ファイル作成

OTA ファイル配布

アップデート更新通知

OTA ファイルダウンロード OTA アップデート アップデート完了

Page 6: Androidのリカバリシステム (Androidのシステムアップデート)

AOSP で対応しているのは?OS ビルド・ OTA ファイル作成

OTA ファイル配布

アップデート更新通知

OTA ファイルダウンロード OTA アップデート アップデート完了

Page 7: Androidのリカバリシステム (Androidのシステムアップデート)

ブロックで書くとOTA ファイル作成

サーバへデプロイ

アップデート存在チェック

OTA ファイルダウンロード

OTA ファイル署名検証

リカバリ再起動

RecoveryConsole起動

OTA ファイル署名検証

OTA ファイル展開

Updater 起動

アップデート適用

再起動し完了

配布側処理 Android

RecoveryConsole

OTA ファイル内Updater

RecoveryOS

赤線枠内がAOSP 対応部分

Page 8: Androidのリカバリシステム (Androidのシステムアップデート)

AOSP 内コンポーネントその1

● Releasetools– Target-files-package(TFP) からデジタル署名さ

れた OTA アップデートファイルを生成するツール– build/tools/releasetools 配下

● Android.os.RecoverySystem API– アップデートファイルの検証・インストールとファクト

リーデータリセットのための Android フレームワーク API

– frameworks/base/core/java/android/os/RecoverySystem.java

Page 9: Androidのリカバリシステム (Androidのシステムアップデート)

AOSP 内コンポーネントその2

● Recovery Console (RC)– Android 内の別ブート環境– システムアップデート処理を起動– ファクトリデータリセットを実行– bootable/recovery 配下

● Updater– アップデートファイル内のアップデートロジックと実

行形式バイナリ– RC から起動され、 Edify と呼ばれる独自スクリプ

トで実行– bootable/recovery 配下

Page 10: Androidのリカバリシステム (Androidのシステムアップデート)

AOSP に無い機能

● アップデートファイル配布サーバ側● システムアップデート更新チェックとダウンロード

処理● 更新の通知 UI

– android.settings.SYSTEM_UPDATE_SETTINGS のインテントを受け付けて設定画面から起動するようにする

Page 11: Androidのリカバリシステム (Androidのシステムアップデート)

リカバリシステムの制限事項

● 再パーティショニングは出来ない– /system が足りなくなったり boot 、 recovery

パーティションが足りなくなっても増やせないので最初に余裕を持った設定をする必要あり

– cache パーティションは system の 2/3程度あれば安全

● 1度に出来るのは 1 アップデート● アップデート中はデバイスの通常使用は出来な

Page 12: Androidのリカバリシステム (Androidのシステムアップデート)

ファイルシステムの設定

Page 13: Androidのリカバリシステム (Androidのシステムアップデート)

Android のパーティションレイアウト

● boot– Linuxカーネルと root ファイルシステムになる

RAM ディスク– init をはじめとした、 /system をマウントし

Android を起動するためのツールが含まれる● system

– 全ての Android のシステムアプリとライブラリを含む

– OTA アップデート時以外は常に Read-only でマウントされる

● ※Lollipop では OTA アップデート時も Read-onlyでマウント (後述 )

Page 14: Androidのリカバリシステム (Androidのシステムアップデート)

Android のパーティションレイアウト

● data– ダウンロードしたアプリ格納– アプリデータ格納– DalvikVM のキャッシュ– OTA アップデートでは何も変更されない– ファクトリデータリセットで消去される

Page 15: Androidのリカバリシステム (Androidのシステムアップデート)

Android のパーティションレイアウト

● recovery– リカバリ OS(互換起動イメージ )格納– RecoveryConsole(RC) の実装をはじめとした

recovery 機能を含む RAM ディスク● misc

– ファイルシステムを含まない非常に小さな領域● Bootloader Control Block(BCB) と呼ばれ、ブ

ロックデバイスとして直接読み書きされる– RC と Bootloader 、カーネル間のやり取りに使わ

れる

Page 16: Androidのリカバリシステム (Androidのシステムアップデート)

Android のパーティションレイアウト

● cache– 一時的なファイル置き場– 特殊な権限 (uid:system) を持つアプリによる一時ストレージやダウンロード領域として使用される

– OTA アップデートファイルもここに置かれる– applypatchが一時ストレージとして使用する– ファクトリデータリセットで消去される

Page 17: Androidのリカバリシステム (Androidのシステムアップデート)

Android Boot イメージ

● メタデータ (boot header) 、カーネルイメージ、 RAM ディスク、 2nd ブートローダー (オプション ) を格納したコンテナファイルフォーマット

● system/core/mkbootimg を使って生成– ファイルフォーマットは

system/core/mkbootimg/bootimg.hで定義– 通常ビルド時と OTA アップデートファイル生成時

に使用される

Page 18: Androidのリカバリシステム (Androidのシステムアップデート)

recovery.fstab

● デバイス上の全ファイルシステムを定義したファイル

– パーティションの定義ではない● RC と Releasetools が使用● デバイスノードのマウントポイントとファイルシステ

ムタイプを記述

Page 19: Androidのリカバリシステム (Androidのシステムアップデート)

Releasetools によるアップデートファイル生成

Page 20: Androidのリカバリシステム (Androidのシステムアップデート)

Targer-Files-Package(TFP)

● 'make target-files-package'で生成– out/target/product/[device]/obj/PACKAGING/target_files_intermediates/ に生成

● OTA アップデートファイル生成に必要な全てが含まれた zip アーカイブ

– フルイメージでのアップデートの場合は TFP は 1つだけ必要

– 差分アップデートの場合は差分の元となる TFP が2 つ必要

Page 21: Androidのリカバリシステム (Androidのシステムアップデート)

Targer-Files-Package(TFP)

● ”radio ファイル”としてデバイス固有 blob を追加可能

– 必ずしも無線に関する機能追加だけではない● bootloader等

– AndroidBoard.mk に以下を追加● $(call add-radio-file,myblob.dat)

– ただ、最近の Nexus デバイスでは使われていないよう

– デバイス向けの Releasetools追加定義で扱う

Page 22: Androidのリカバリシステム (Androidのシステムアップデート)

Android セキュリティ

● 全ての APKは電子署名される– 同じアプリのバージョンアップとして扱われるには同じ証明書で署名される必要がある

– 複数のアプリで同じユーザー ID を共有するのにもそれらのアプリが同じ証明書で署名される必要がある

– LOCAL_CERTIFICATE として定義された証明書を使用。

● デフォルトでは testkey を使用

Page 23: Androidのリカバリシステム (Androidのシステムアップデート)

Android セキュリティ

● AOSP は build/target/product/security に以下の 4つの証明書キーを持っている

– testkey:APK署名のデフォルトキー– platform: コアプラットフォーム署名向け– shared:ホームと連絡先アプリのプロセス間で共有されるプロバイダ向け

– media:メディア / ダウンロードプロバイダ向け

Page 24: Androidのリカバリシステム (Androidのシステムアップデート)

Android セキュリティ

● AOSP のキーでは製品版としては使えない– CTS を含む開発時のみ使用– Releasetools に含まれる

sign_target_files_apks を使って TFP 内のAPKを製品用キーで再署名する必要がある

● RC 内の OTA 検証キーも製品用キーに変換される

Page 25: Androidのリカバリシステム (Androidのシステムアップデート)

ota_from_target_files

● TFP から OTA アップデートファイルを生成するための Python スクリプト

– ota_from_target_files [flags] input_target_files output_ota_package

– (--incremental_from) <file>● 差分アップデート時に差分の元となる TFP を指定

– (--wipe_user_data)● OTA で /data を消去

– (--package_key) <key>● パッケージ署名に使うキーを指定

– デフォルトは testkey

Page 26: Androidのリカバリシステム (Androidのシステムアップデート)

ota_from_target_files

● Python の拡張としてデバイス独自のアップデートタスクを追加可能

● 全てのアップデートに必要なイメージ、 Updater実行バイナリ、アップデート時に使用されるedify スクリプトを含むパッケージを生成

Page 27: Androidのリカバリシステム (Androidのシステムアップデート)

アップデートファイル生成まとめ

Android ビルド

TFP( Test Key使用)

APK 再署名 TFP

差分アップデート元 TFP

アップデートファイル生成

アップデートファイル

make target-files-package

sign_target_files_apksota_from_target_files

差分アップデートファイルの生成場合必要

Page 28: Androidのリカバリシステム (Androidのシステムアップデート)

Releasetools拡張

● Releasetools を拡張するには以下のファンクションを実装した Python モジュールを作成する必要がある

– FullOTA_Assertion()– FullOTA_InstallEnd()– IncrementalOTA_Assertion()– IncrementalOTA_VerifyEnd()– IncrementalOTA_InstallEnd()

● モジュールを置いたパスを BoardConfig.mk にTARGET_RELEASETOOLS_EXTENSIONS として記述する

Page 29: Androidのリカバリシステム (Androidのシステムアップデート)

その他の Releasetools

● img_from_target_files– 'fastboot update' 向けの zip アーカイブを生成

● check_target_files_signature– TFP に含まれるパッケージの署名をチェックする– 差分アップデート用の 2 つの TFP の互換性チェッ

クに使用

Page 30: Androidのリカバリシステム (Androidのシステムアップデート)

RecoverySystem API

Page 31: Androidのリカバリシステム (Androidのシステムアップデート)

RecoverySystem API

● android.os.RecoverySystem としてアプリから使用可能な API

– REBOOT のパーミッションが必要– /cache の読み書き権限も必要なので systemユーザー向け API

● /cache/recovery/command にコマンド (OTAアップデート / ファクトリデータリセット ) 、アップデートファイルパスを書き込み、 OS 再起動後にRecovery Console へ伝える

● アップデートファイルの検証を実行– /system/etc/security/otacerts.zip をデフォル

トでは検証に使用

Page 32: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery Console (RC)

Page 33: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery Console

● リカバリ用の起動イメージ– シェルから’ reboot recovery’で起動– RecoverySystem API から起動– ベンダーが実装するブートローダーからの操作と

して起動● UI は画像ベース、ローカライゼーションにも対応● 手動操作向けの隠しメニュー

– ファクトリデータリセット– SD カードからのアップデート– UI プラグインでデバイス固有の機能追加可能

Page 34: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery Console

● ログは /cache/recovery に保存される– RC と Updater の標準出力・エラーの出力先– Edify の ui_print() コマンド出力先

Page 35: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery Console の制御

● RC 起動時は以下をコマンドライン引数としてチェックする

– recovery コマンドの引数 デバッグ用途のみ– BCB の recovery パラメータ– /cache/recovery/command ファイル

(RecoverySystem API が書き込み )● 起動時に引数を BCB に常に保存

– アップデート中の不意の電源断時に再度ブートローダーがリカバリ OS を起動するようにする

Page 36: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery Console の制御

● finish_recovery()– アップデート、ファクトリデータリセットなど処理が

成功 /失敗に関わらず終了する時に実行– BCB をクリアして Android を起動するようにする– ログを /cache/recovery にコピー

Page 37: Androidのリカバリシステム (Androidのシステムアップデート)

ブートローダーとの調整

● カーネルは reboot() の引数として” recovery” が与えられたら、 BCB のcommand パラメータに” boot-recovery” を書き、 recovery パラメータを 0 クリアする

– ドライバの register_reboot_notifier() で実装する

● ブートローダーは起動イメージを BCB のcommand パラメータで判断する

– RC が command パラメータを消去するまでは RCを起動

– command が消去されていれば通常の Android起動

Page 38: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery Console UI プラグイン

● RC へデバイス固有の拡張を追加可能– BoardConfig.mk の

TARGET_RECOVERY_UI_LIB にライブラリの$(LOCAL_MODULE) を定義する

– bootable/recovery/device.hで定義されるDevice クラスを実装することで独自拡張可能

– device/htc/fugu/recovery以下に実装サンプルあり

Page 39: Androidのリカバリシステム (Androidのシステムアップデート)

Recovery 画面

● GUI は画像ベース● bootable/recovery/ 配下の res-mdpi〜 res-xxxhdpi に標準の画像があり、差し替え可能

– RGB/RGBA フォーマットの 8bit PNG ファイル– ファイル名は同じままにしておく

● bootable/recovery/interlace-frames.py としてアニメーションの作成に使えるスクリプトが準備されている

– ベース画像とオーバーレイする複数フレームを一枚画像にする

Page 40: Androidのリカバリシステム (Androidのシステムアップデート)

Updater

Page 41: Androidのリカバリシステム (Androidのシステムアップデート)

Updater 実行バイナリ

● アップデートファイル内に含まれる– zip ファイルに含まれることで、アップデートの実装

コードが既存に存在している必要が無くなる● 必ずしも AOSP の Updater 実装を使用する必要

はない– RC は Updater を fork()/exec() で実行し、 pipe

で通信する– RC は引数を 3 つ渡す

● Android.mk で定義された RC API バージョン(Android2.2〜 5.0 でバージョン 3)

● pipe のファイルディスクリプタ● アップデート zip ファイルパス

Page 42: Androidのリカバリシステム (Androidのシステムアップデート)

Updater 実行バイナリ

– Updater は画面 ( 進捗表示 )表示制御や文字表示、 cache消去などの文字列コマンドを pipe経由で RC に送信する

● bootable/recovery/install.cpp参照● AOSP 実装Updater はアップデートファイル内の

Edify で記述されたスクリプトを実行する● デバイス固有の Updater 機能はプラグインとし

て実装可能● Updater の中断処理には注意 ! 正しく実装しな

いと文鎮化してしまう

Page 43: Androidのリカバリシステム (Androidのシステムアップデート)

起動からのリカバリ処理

● RC 自体は OTA アップデートの処理中はアップデートされない

– 不意の電源断後も同じ RC が使用されることを確実にするため

● flash_recovery– init.rc の oneshot service として実行– /system/etc/install-recovery.shを実行– recovery イメージの SHA1ハッシュをチェックして

パッチを当てる必要があるか判断– 必要があれば recovery パーティションの起動イメージにパッチを当てる

Page 44: Androidのリカバリシステム (Androidのシステムアップデート)

Applypatch

● 差分アップデート時に /system のファイルとboot イメージにパッチを当てるのに使用

● bootable/recovery/applypatch配下● 差分作成は bsdiff を使用● 安全に (望むタイミングまで元ファイルは touch

されない ) 、冪等に (1 回操作を行っても何度行っても同じ結果になる ) なるよう処理される

Page 45: Androidのリカバリシステム (Androidのシステムアップデート)

Edify スクリプト

● OTA アップデートのためのスクリプト言語● bootable/recovery/edify 配下● 文法など詳細は README ファイル参照● 全ての関数は C で実装、 Edify では関数定義出

来ない● 組み込み関数

は /bootable/recovery/updater/install.cに実装、プラグインとして関数追加可能

Page 46: Androidのリカバリシステム (Androidのシステムアップデート)

Updater プラグイン

● ライブラリとして複数の追加定義が可能– Static ライブラリとして作成– BoardConfig.mk に

TARGET_RECOVERY_UPDATE_LIBS としてライブラリ名を定義

– サンプル実装としてdevice/asus/fugu/recovery を参照

– TARGET_RECOVERY_UPDATE_EXTRA_LIBSとして Static ライブラリのバイナリ ( サポートライブラリ ) を追加定義可能

Page 47: Androidのリカバリシステム (Androidのシステムアップデート)

製品化タスク

● recovery.fstab の定義作成● デバイス独自 blob を” radio ファイル”として

AndroidBoard.mk に追加● RC UI プラグイン実装

– リカバリ時の画像を必要なら差し替え● Updater プラグイン実装

Page 48: Androidのリカバリシステム (Androidのシステムアップデート)

製品化タスク

● Releasetools拡張実装– OTA アップデートファイルへの RADIO イメージの追加・パッチのロジックを追加

– イメージを扱う Edify コマンドの Updater スクリプトへの追加

– 必要ならアサーション・ベリフィケーション処理を追加

● BoardConfig.mk にプラグイン、拡張、サポートライブラリの定義を追加

● 設定アプリから IntentFilter で OTA アップデートファイルダウンロード処理を呼べるようを実装

Page 49: Androidのリカバリシステム (Androidのシステムアップデート)

製品化タスク

● ブートローダーとカーネルで BCB を介してやり取りできるよう実装

● 製品用証明書キー生成● Android フレームワー

ク、 build/core 、 bootable/recovery は変更の必要なし

● 良い継続的なテストを計画しましょう

Page 50: Androidのリカバリシステム (Androidのシステムアップデート)

Lollipop での新機能

Page 51: Androidのリカバリシステム (Androidのシステムアップデート)

Secureboot

● 読み取り専用パーティションの整合性を保証する機能が Lollipop から有効化

– Linuxカーネルの DM-Verity を使用– パーティションを 4k バイトブロックに分け、各ブロッ

クのハッシュ値からハッシュツリーを生成

Page 52: Androidのリカバリシステム (Androidのシステムアップデート)

DM-Verity

● パーティションへの書き込み要求がある毎にカーネルモジュールがブロック単位でハッシュをチェック、不整合が発生したら I/Oエラーを返すことでパーティションを保護

● /system と /vendor に適用されている● system/extras/verity にユーティリティが追加● 詳細はhttps://source.android.com/devices/tech/security/secureboot/index.html

Page 53: Androidのリカバリシステム (Androidのシステムアップデート)

リカバリシステムへの影響

● リカバリ OS はファイルシステム経由で /systemを書き換える

– →DM-Verity が有効だと書き換えにより不整合が発生

– →文鎮化● 解決方法としてブロック指向の OTA(block-

oriented OTAs) を導入

Page 54: Androidのリカバリシステム (Androidのシステムアップデート)

ブロック指向OTA

● ファイルの差分ではなくブロックの差分を使用● ファイルシステムを介さず、ブロックデバイスを直接書き換える (MTD デバイスなら MTD サブシステム経由 )

● ファイルシステムを介さない分処理も高速化● リカバリ OS でも /system は Read-only としてマ

ウントされるようになり、書き込み直前にアンマウントされるよう変更されている

Page 55: Androidのリカバリシステム (Androidのシステムアップデート)

参考資料

● Android Builders Summit 2012 ”Android* Software Updates”

– https://events.linuxfoundation.org/images/stories/pdf/lf_abs12_boie.pdf

– http://free-electrons.com/blog/abs-2012-videos/

● Android Open Source Project “Android Core Technologies Secure Boot”

– https://source.android.com/devices/tech/security/secureboot/index.html

● Androidソースコード検索サービス

– https://sites.google.com/site/devcollaboration/codesearch