先日よりコメント欄で、ブートローダーがロックされた端末向けのカスタムROMの作り方についてやり取りをしていたのですが、出来上がったノウハウを共有して広めるのも良いかなと思い、ビルド手順を分かりやすく解説することにしました。
おおまかな流れ
- ビルドしたいROMのソースを取得
- ビルドしたいROM向けのデバイスツリーを用意
- ビルド対象の端末のストックカーネルソースを取得
- ビルドしたいROMのソースツリーにストックカーネルソースを適切に配置
- デバイスツリーを編集してストックカーネルソースとdefconfigを使うようにする
- デバイスツリーを編集してストックカーネルが対応しない機能を削るために、フラグを追加、削除
- ストックカーネルを使う際に問題が起こるdisplay HAL、media HALあたりを編集
- その他、ストックカーネル向けに変更した方が良い部分を適宜修正(特にSELinuxの動作モードについてはsepolicyなりinitなりを編集してpermissiveかdisabledにする)
- ビルドが成功するまで、何度もトライアンドエラーでエラー箇所を修正
- ビルドが成功したら、出来上がったROMとramdiskを取り出す
- hijack-ramdisk内のシェルスクリプトを対象端末向けに調整して、出来上がったramdiskも中に入れる
- 出来上がったROMとhijack-ramdiskを実機に導入して、機能的なバグがあればデバイスツリーを修正して再ビルド
実践
上記の流れに沿って実際にブートローダーがロックされた端末向けに作業してみます。
例としてhayabusa(GX)を使っても良いのですが、せっかく一から書き起こすので新規にhuashan(SP)向けにCM12.1をビルドしてみます。
*ここでは標準的なROMのビルド環境は全て整っている前提で話を進めます
1. CM12.1のソースを用意
repo init -u https://github.com/CyanogenMod/android.git -b cm-12.1
repo sync -j16
2. huashanのデバイスツリーを用意
. build/envsetup.sh
breakfast huashan
huashanのデバイスツリーとCMのカーネルソースがダウンロードされます。
デバイスツリーを用意したら、実機をつないでプロプライエタリなファイルを取り出すのですが、ここでは便宜上、TheMuppetsから拝借します。
svn checkout https://github.com/TheMuppets/proprietary_vendor_sony/trunk/huashan
ワーキングディレクトリにベンダーファイルを含んだ"huashan"というフォルダが作られます。
3. huashanのストックカーネルソースを入手
huashanのストックカーネルソースをSony Developer World の Xperia open source archivesで手に入れます。
huashanの最終ビルドは12.1.A.1.207なので、それ用を使いましょう。
ソースは圧縮されているので適当なアーカイバで解凍して、中のkernelフォルダを取り出します。
"kernel"では分かりにくいので、仮に"viskan"と名前を変更します。
(huashanのプラットフォームはviskanというそうです。blueとGPU以外同じSoCで互換性も高いのにわざわざ分けられているのですね。)
4. デバイスツリー、ベンダーファイル、カーネルソースを配置
ストックカーネルソースとベンダーファイルを用意したら、CMのソースツリーが以下の形になるように配置して下さい。
CM12.1-huashan
├── abi
├── android
├── art
├── bionic
├── bootable
├── build
├── cts
├── dalvik
├── developers
├── development
├── device
├── docs
├── external
├── frameworks
├── hardware
├── libcore
├── libnativehelper
├── ndk
├── packages
├── pdk
├── prebuilts
├── sdk
├── system
├── tools
├── kernel
│ └── sony
│ ├── msm8960t
│ └── viskan
├── vendor
│ ├── cm
│ ├── cmsdk
│ └── sony
│ └── huashan
└── Makefile
5. デバイスツリーをストックカーネル向けに編集
ここからは、huashanのデバイスツリーをストックカーネル向けに編集します。
使用するカーネルソースとdefconfigの場所を変更します。
device/sony/huashan/BoardConfig.mk
# Kernel properties
TARGET_KERNEL_SOURCE := kernel/sony/viskan
TARGET_KERNEL_CONFIG := viskan_huashan_defconfig
メディア、ディスプレイ、オーディオHALはcaf版を使うので、そちらも追記
device/sony/huashan/BoardConfig.mk
# QCOM/CAF hardware
COMMON_GLOBAL_CFLAGS += -DQCOM_HARDWARE
BOARD_USES_QCOM_HARDWARE := true
TARGET_QCOM_AUDIO_VARIANT := caf
TARGET_QCOM_DISPLAY_VARIANT := caf
TARGET_QCOM_MEDIA_VARIANT := caf
# QCOM enhanced A/V
TARGET_ENABLE_QC_AV_ENHANCEMENTS := true
同時にDisplay HALの不要なフラグを削除かコメントアウト
# Display HAL
USE_OPENGL_RENDERER := true
TARGET_USES_ION := true
TARGET_USES_C2D_COMPOSITION := true
#TARGET_DISPLAY_USE_RETIRE_FENCE := true
NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
6. ストックカーネルに合わせてmedia-cafとdisplay-cafを入れ替える
本来は個別にビルド時のエラー箇所を修正する必要がありますが、今回は関連箇所のコミットをリバート済みのリポジトリを使わせてもらいます。
hardware/qcom/display-caf/msm8960
hardware/qcom/media-caf/msm8960
二箇所のフォルダを入れ替える
7. その他、ストックカーネル向けの変更
huashanのストックカーネルソースはGCC4.7でビルドされていますが、CM12.1はGCC4.9でビルドされるので、それ用の変更をカーネスソースに加えます。
kernel/drivers/usb/gadget/Makefile
kernel/net/bluetooth/Makefile
KBUILD_CFLAGS += -Wno-sizeof-pointer-memaccess
Android 5.1のSELinuxの制限を緩めるために、sepolicyを編集
external/sepolicy/Android.mk
FORCE_PERMISSIVE_TO_UNCONFINED:=false
このままビルドするとzip内のカーネルが自ビルドのものになるので、適宜ストックカーネルと入れ替えるようにする。(詳しくは、そのうち今回のソースを公開するので、そちらを見てください)
8. ビルド開始
さて、これで準備が出来ました。いよいよビルドを始めます。
brunch huashan
全てが適切に編集されていればビルドが通るはずです。
まとめ
今回作成したブートローダーがロックされたXperia SP用のCM12.1のROMとSP向けのhijack-ramdiskを公開します。ただ、実機で動作確認できないので、起動しないかも知れません。
cm-12.1-20151204-UNOFFICIAL-huashan
huashan hijack-ramdisk for CM12.1
Xperia SPを持っていて試される方がいれば、結果を教えてください。
流れとしては以上のようになりますが、見れば分かるとおり、それなりに処理の内容を理解してエラーに対処できる程度の知識がないと難しいです。ただリポジトリを引っ張ってきてビルドするレベルからのステップアップには良いかと思います。