Android: Nexus S に公式版2.3.6をインストール

あけましておめでとうございます。

正月からさっそくAndroidを触っています。



去年11月にネットでNexus Sを購入し、自動通知に従いOTAにより2.3.4から2.3.6にアップデートし、その後、master branchのソースをコンパイルしてインストールしたり、カスタム版のAndroid4.0.1をインストールしたりと、色々と実験していたのですが、ネット上に公式の2.3.6のFull updateがあったので、これを使ってNexus Sの現時点での最新バージョンである2.3.6に戻しました。(公式版4.0.3へのアップデートの準備でもあります)

購入時に2.3.6にアップデートした時と同じバージョンに戻ったことを端末情報の表示で確認しました。
   

以下、2.3.6をインストールした手順です。

1. 公式版2.3.6のFull update(1ada25375426.signed-soju-ota-189904.1ada2537.zip)をダウンロード
forum.xda-developers.comの以下の投稿に従い、ダウンロードしました。

http://forum.xda-developers.com/showthread.php?t=1056062

Model: Nexus i9020t/i9023
GRJ22 (2.3.4) - > GRK39F (2.3.6) Released   ←2.3.4からの差分によるアップデート。サイズは18MB。
Full ROM update -> GRK39F (2.3.6) Released  ←フルアップデート。こちらを使用。サイズは98MB。

(同じページにはModel: Nexus i9020a 用のアップデートへのリンクもあります。
私の購入したNexus Sは上記の端末情報画面のベースバンドバージョンに表示されている通り、i9023でした。 - 01/03/2012 追記)

ダウンロードのリンク先はandroid.clients.google.com となっています。
http://android.clients.google.com/packages/ota/google_crespo/1ada2537542...

2. ダウンロードしたzipファイルをupdate.zipとか適当な名前(元の名前は長い)で/mnt/sdcardの下にadbコマンドでpushする
 (recoveryのメニューから選択できるので、ファイル名は適当で良い。/mnt/sdcardの下のサブディレクトリでも良い。)

3. recovery-clockworkをダウンロードし、fastbootコマンドで"recovery"パーティションに書き込む
 (googleオリジナルのrecoveryを使った時は、verificationでfailしました)

4. fastbootコマンドで"cache"と"userdata"のパーティションをeraseする

# fastboot erase cache
# fastboot erase userdata

cacheとuserdataはAndroidのバージョンが異なると整合性がないようです。この操作をしておかないと、アップデート後、正常に立ち上がりませんでした。
こちら の"Flashing a device"の項にも関係する記述があります。

5. フルアップデートのzipファイルを解凍し、その中のboot.imgをfastbootコマンドで"boot"パーティションに書き込む
 (アップデートの実行の最後にboot.imgの書き込みで失敗するので、その対処。他にもっと良い方法があるかも)

6. recoveryモード(recovery-clockwork)でアップデートを実行する
 /mnt/sdcardの下にコピーしておいた上記アップデートファイルをメニューから指定してインストールする。
 終わったら、rebootメニューを選んで再起動すると2.3.6が立ち上がります。

以上のステップ2,3,5,6の手順はカスタム版Android4.0.1をインストールした時と同じです。こちらを参考に→ "カスタムAndroid4.0をNexus Sにインストール"

[参考]

アップデートには前のバージョンからの差分のアップデートと、すべてを入れ替えるフルアップデートがあり、差分のアップデートは普通は自動通知で行なわれ(ファイルをダウンロードして手作業でもできる)、フルアップデートは例外的なもので、今回のように手作業でおこなうようです。

いくつかのアップデートを試してみたところ、どのzipファイルも決まった構成になっていました。
今回の1ada25375426.signed-soju-ota-189904.1ada2537.zipを解凍すると、

$ ls
META-INF  boot.img  bootloader.img  radio.img  recovery  system

アップデートを実行するバイナリとスクリプトが以下のディレクトリにあります。
$ ls -l META-INF/com/google/android
合計 220
-rw-rw-r--. 1 rotake rotake 215948 11月 29  2010 update-binary
-rw-rw-r--. 1 rotake rotake   3617 11月 29  2010 updater-script

バイナリのupdate-binaryがスクリプトupdater-scriptを実行するようです。
updater-scriptは、現行の/system/build.propファイルをassertコマンドによりチェックして、アップデートを適用できるかどうか判定しています。
なので、updater-scriptのassertコマンドの内容と現行の/system/build.propファイルを事前に比較すれば、アップデートを適用できるかどうかの見当をつけることができます。

フルアップデート(1ada25375426.signed-soju-ota-189904.1ada2537.zip) の updater-scriptの抜粋:

assert(!less_than_int(1316544229, getprop("ro.build.date.utc")));
assert(getprop("ro.product.device") == "crespo" ||
       getprop("ro.build.product") == "crespo");
show_progress(0.500000, 0);
format("ext4", "EMMC", "/dev/block/platform/s3c-sdhci.0/by-name/system");
mount("ext4", "EMMC", "/dev/block/platform/s3c-sdhci.0/by-name/system", "/system");
package_extract_dir("recovery", "/system");
package_extract_dir("system", "/system");
........................................

差分アップデート(7d11404284c0.signed-soju-GRK39F-from-GRJ22.7d114042.zip)のupdater-scriptの抜粋:

mount("ext4", "EMMC", "/dev/block/platform/s3c-sdhci.0/by-name/system", "/system");
assert(file_getprop("/system/build.prop", "ro.build.fingerprint") == "google/soju/crespo:2.3.4/GRJ22/121341:user/release-keys" ||
       file_getprop("/system/build.prop", "ro.build.fingerprint") == "google/soju/crespo:2.3.6/GRK39F/189904:user/release-keys");
assert(getprop("ro.product.device") == "crespo" ||
       getprop("ro.build.product") == "crespo");
ui_print("Verifying current system...");
show_progress(0.100000, 0);
...........................................

2.3.6にアップデート後の/system/build.propファイルの抜粋:

ro.build.date.utc=1316544229
ro.product.name=soju
ro.product.device=crespo
ro.build.product=crespo
ro.build.fingerprint=google/soju/crespo:2.3.6/GRK39F/189904:user/release-keys