深く考えずにFirefox OSの移植に挑戦!……中です。【後編】

by Kenichiro Mitsuda  2014/04/7

1. ボードコンピュータでFirefox OS動かしたい!

1.1. これまでのあらすじ

会社にあった何かの評価用のボードコンピュータで、イマドキのリッチなUIを持つOSを動かしてみる事になった。イマドキのリッチなUIをもつOSで、かつ、ソースコードがさわれるものと言うことで、真っ先にAndroidが思い浮かんだものの、移植ターゲットとするボードコンピュータは最近のAndroidをゴリゴリ動かせるほどパワーが無いのだった。そんな現実に打ちひしがれていたある日、Firefox OSならば

     

      • Android 4.0(Ice Cream Sandwich)以降が動作しているなら移植は可能

      • メインメモリ256MByteでも動作可能。将来的に 128MByteでも動作する予定という情報をGet!

    「Firefox OSアプリ開発ガイド」を頼りに、BeagleBoard-xMで移植手順を確認した後、ターゲットボードへの移植を開始したものの、最初の挑戦はアッサリと失敗に終わった。

      ベースとなるAndroid ターゲットボードで のAndroid動作実績 Firefox OSの移植可否
    Step1 Android-4.1(JB) 動作する Android(JB4.1)側がFirefox OSの移植対象外のため失敗
    Tbl. 1-1-前編での移植作業結果

    1.2. 後編のあらまし

    本稿では、前編に引き続き、移植ベースとなるAndroidや移植対象とするFirefox OSのバージョンを変えながら行った作業についてざっくばらんに書きました。
    前編の冒頭にあるとおり、本稿執筆段階ではFirefox OSの移植に成功しておりません。
    よって、Firefox OSの移植を成功させるための情報を求めている方には大変申し訳ありませんが、せめて、本稿に書かれた失敗を繰り返さないようにしていただければと思います。

    本文の中では特に断りなくmanifestファイルに対する操作が出てきます。manifestファイルになじみのない方のために、かんたんな解説「Android manifestファイル解説~超ざっくり編」を用意してあるので、必要に応じて参照してください。

    2.ターゲットボードへの移植 2回目
    Firefox OS v1-train + Android(ICS)

    2.1. manifestファイルの作成

    AOSPから4.0.4_r2.1のmanifestファイルをダウンロードし、これをベースに再びmanifestファイルを作り直す。やはり、android-4.1.2_r1の物と比較すると、含まれているプロジェクトも結構差分があるようだ。
    1回目と同様、不要なプロジェクトの削除&ターゲットボード依存のプロジェクトを追加。

    2.2. ソースコード取得

    今回はちゃんと取得完了。

    2.3. ソースコードの修正

    1回目で行った修正に加え、Androidのバージョン間の差分の影響箇所修正。
    なぜかログ出力関数名が軒並み変更に。どうやらICS→JBになったときに関数名もLOG~からALOG~に変わってたらしい。何のために?

    2.4. Firefox OSのビルド

    今度はある程度進んだところでlibwpa_client.soのリンクが失敗 orz
    どうやらWi-Fiデーモンのモジュール wpa_supplicantが問題らしい。manifestファイルを調べてみると、wpa_supplicantと名の付くプロジェクトは/external配下に3つもある。
    wpa_supplicant
    wpa_supplicant_6
    wpa_supplicant_8

    実は、android-4.1.2_r1をビルドしていたときは、このうちwpa_supplicant_8が使われていたが、android-4.0.4_r2.1では無印のwpa_supplicantを使うのが正解だった。で、このバージョンを設定している箇所は、ターゲットボード向けに実装されたファイルBoardConfig.mkの”WPA_SUPPLICANT_VERSION := VER_0_8_X” でした。
    そんなわけで、この行を削除。
    これでやっとビルドが通った!


    教訓:

       

        • Androidのバージョンが変わると、manifestファイルには表れない、プロジェクト間でもバージョン依存関係が変わることがある。


      2.5. ブート用SDカードの作成

      Hands-onでは、テキサスインスツルメンツ(TI) のツールを使用してSDカードを作成していたけれど、ターゲットボードに対してはそのままでは使えなさそう。
      でも、とりあえずそれらのスクリプトやmkbootscr、あとinit.rcファイルを参考にして、Hands-onと同様の方法で起動するSDカードを作成。


      COLUMN— ブート用SDカードの中身

      ブード用のSDカードを作るの流儀やコツも実はいろいろとありそう。
      ハンズオンで作成したbeagleboard-xM/rowboart(TI)ではSDカードを

      パーテーション1 パーテーション2 パーテーション3
      Boot領域 MLO, u-boot.bin, uImaze Firefox OSのユーザランド (rootファイルシステム) Firefox OSから見えるデータストレージ領域

      として使用している。
      それに対して、今回のターゲットボードのAndroidではSDカードを分割せず、ブート用プログラムとユーザランドのディスクイメージファイルを直に配置している。

      パーテーション1
      Boot用プログラム:BOOT.bin, devicetree.dtb, zImage
      ユーザランドのディスクイメージ:rootfs.Image.gz, system.img, data.img

      ターゲットボードでこのようになっている理由は、「元々のAndroidのオープンソース(AOSP)がそのような実装になっていたから」というだけ…。

      おそらく、beagleboard-xMのようなベタに展開しておく方法は、実験用途でライブラリやアプリを入れ替える機会が多い場合なんかには良さそう。あと、起動時にファイルを解凍する必要がないため、起動時間も早くなると思う。それ比べて、AOSPのような方法のメリットはユーザがファイルシステムの中身を簡単にいじれないように出来たり、OTAアップデートのような、バージョンアップを配信するための仕組みが作りやすいのだと思う。
      どちらの方法を使うにしても、ブート用SDカードの中身や起動方法をシステムに正しく認識させるためには、少なくとも以下のファイルを設定する必要があるみたい。

         

          • Boardconfig.mk

          • デバイスツリー(TIではmkbootscr)

          • init.rc


         

        2.6. 動作確認

        ターゲットボードにUSBシリアル接続のターミナル、キーボード&マウス、HDMIからディスプレイを接続しSDカードを装着し電源ON。
        ターミナルからlinuxカーネルの起動完了OK!
        ユーザランドのinit処理が始まり、ターミナルにコマンドプロンプトが出た。
        一方、ディスプレイには”A N D R O I D”という文字列が一瞬映った後、再び何も映らなくなってそのまま……。
        再びターミナルを見ると、initタスクの中でいろんなエラーが出た上、CPU usageが100%になってOOM KillerでAndroidがリセットという流れらしい。これはFirefox OSの問題というよりも、もっと深いところが原因な気がする。なんだか、電源管理まわりで状態遷移がうまくいってなさそうだし。ひょっとしてLinux kernel側の電源管理との相性が悪さしているかも……。
        ちょっと気になったので、Wikipediaの「Androidのバージョン履歴」、を見てみると、Androidとlinux kernel間のバージョンの関係は、ICSの動作条件がLinux kernel 3.0以上JBのそれは3.1.10以降となっている模様。
        これも先ほどのAndroidとFirefox OSのバージョン関係の表に追加しておこう。

        Linux Android (AOSP) Firefox OS (B2G)
        kernel Code name Version API Level v1-train
        version
        3.0~ Ice Cream Sandwich android-4.0.4_r2.1 15
        3.1.10~ Jelly Bean (4.1) (省略) 16 未サポート
            android-4.1.2_r1 16
            (省略) 16
        Tbl. 2-1 Linux kernelとAndroid. Firefox OSのバージョン依存関係 (抜粋)

        一方で、ターゲットボードのBSPはLinux kernel 3.3がベース。kernel 3.3はそれ以前のkernelには含まれていなかったAndroid向けの独自拡張をマージした版でリリースは2012年3月。リリース時期から見ると、android-4.0.4_r2.1の開発中にはまだリリースされていなかったkernel……。もしかしたら、このカーネルはJB以降じゃないとまずいのかしら?(でもLinaroのリリースを見てるとkernel-3.4+anroid-4.0.4も動いてるみたいだけど…)
        とりあえず、今はあまり深く考えずAndroidのバージョンをJBに変えてやり直すことにした。


        教訓:

           

            • linux kernelとAndroidのバージョンも確認しておくこと。


          3. ターゲットボードへの移植 3回目
          Firefox OS v1.2 + Android(JB4.3)

          そもそも、最初にトライしていたv1-trainブランチはICSしかサポートしていない。
          なので、JBをベースにしたFirefox OSを使うためには、おのずと他のブランチに切り替える必要がある。
          そこで、オフィシャルサイトのFirefox OSのリリース・ブランチ情報を扱ったページ
          https://wiki.mozilla.org/Release_Management/B2G_Landing
          を調べてみると、v1-trainの他に、リリース用にはv1.2, v1.3という2つのブランチがあって、現状ではv1.2の方が安定していることが分かった。

          3.1. manifestファイルの作成

          b2g-manifestの v1.2ブランチをcheckoutして中身を確認してみる。
          すると、実機では唯一nexus-4がandroid-4.3_r2.1 (JB 4.3)ベースのFirefox OSをサポートしている模様。さらにmanifestファイルの作りにも改善があり、nexus-4のmanifestファイルnexus-4.xmlでは先頭でまずbase-jb.xmlをincludeしたうえで、その他のハードウェアに依存するプロジェクトが定義されている。base-jb.xmlの中身を見ると、Firefox OSで必要なプロジェクトがあらかじめまとめてある!
          これはわかりやすいし非常にありがたい!
          よって今回のmanifestファイルは、base-jb.xml をincludeしたうえで要素のファイルダウンロード元にAOSPを指定し、ターゲットボード向けのプロジェクトを追加するだけでサクッと完成!
          と言いたいけど、じつはベースとするAndroidのバージョン(revision)で少々悩む。

          もともとターゲットボードはandroid-4.1.2 (JB 4.1)の動作実績しかなかった。それがいきなりJB 4.3となるとAndroidそれ自体の差分も大きく、ビルドを通すのも難しそうな予感。
          せめて、Android 4.2系でFirefox OSが動かないかなぁと思い、git log -pコマンドを使ってnexus-4.xmlの履歴と変更箇所を洗ってみる。

          </p>
          &gt; git log -p nexus-4.xml
          
          &lt;中略&gt;
          commit f879f87893f7173d233b049852430e69b556866a
          Author: Michael Wu &lt;mwu@mozilla.com&gt;
          Date:   Mon Jul 29 19:55:05 2013 -0400
          
              Upgrade JB devices to MR2
          
              Change-Id: I3c241ecd99086227b5c5a1f5e512154c72120c0f
          
          diff --git a/nexus-4.xml b/nexus-4.xml
          index e6606db..d489d00 100644
          --- a/nexus-4.xml
          +++ b/nexus-4.xml
          @@ -2,20 +2,17 @@
          
             &lt;include name="base-jb.xml"/&gt;
          
          -  &lt;default remote="aosp" revision="refs/tags/android-4.2.2_r1" sync-j="4"/&gt;
          +  &lt;default remote="aosp" revision="refs/tags/android-4.3_r2.1" sync-j="4"/&gt;
          
          &lt;後略&gt;
          <p>

          list.3-1 git log -pコマンドによる変更ログおよび変更箇所の表示(抜粋)

          なるほど、2013/7/29のコミット(ID: f879f87)で、ベースとするandroidのバージョンが
          android-4.2.2_r1からandroid-4.3_r2.1に変更(rebase)されたことが分かった。
          もちろん、このrebaseの直前でandroid-4.2.2_r1でどの程度動作していたかは不明。なのでやっぱり今回の移植のベースにはできないけれど、一応逃げ道としてメモしておこう。

          Linux Android (AOSP) Firefox OS (B2G)
          kernel Code name Version API Level v1-train v1.2 v1.2
          version
          3.0~ ICS 4.0.4_r2.1 15
          3.1.10~ JB (4.1) 4.1.2_r1 16
            JB-mr1 (4.2) 4.2.2_r1 17
            JB-mr2 (4.3) 4.3_r2.1 18
          Tbl. 3-1 Linux kernelとAndroid. Firefox OSのバージョン依存関係 (抜粋)

          と言うわけで、次にトライするFirefox OSのベースandroid-4.3_r2.1に決定!
          ってこの話、最初にやめた「最近のAndroid (JB 4.3)の移植」となんら変わらない
          ∑(゚Д゚)
          まぁ、でも最初と違って、今の段階では「最近のAndroid (JB 4.3)の移植」することにも「Firefox OSを動かすため」という理由が出来た。ついでに、最新のモバイルOS事情も含めてノウハウを増やす!


          教訓:

             

              • ちゃんと考えてポーティングしよう。


             

            Android manifestファイル解説~超ざっくり編 (PDF)
            Linux kernel, AndroidとFirefox OSの関係 (バージョンについて)他資料(ZIP)


            深く考えずにFirefox OSの移植に挑戦!……中です。【前編】