Galaxy S4(SC-04E)用のcrDroid 8.0、カスタムROMを作った時の忘備録メモ

ソース入手

メモ)repoするとsystem/coreの生成に失敗した

.repo/manifests/snippets/crdroid.xmlを修正する

-<project path="system/core" name="crdroidandroid/android_system_core" remote="crdroid" />
+<project path="system/core" name="crdroidandroid/android_system_core_old" remote="crdroid" />

GitHubのソースツリーを変更しても、repoのmanifest関連は前のまま放置されていることが多い

メモ)deviceツリーソースについて

ベースとしてvzw版のブランチ:lineage-15.1を使う、ブランチ:lineage-15.0はうまくビルド出来ないことが分かっている。 さらにlineage-15.1でもvzw版しか作られていない

用意するのは、kernel、device、vendorの3つ

SC04Eではboot.imgの書き込みにlokiが必要

lokiのソースはvzw版のreleasetoolsにある。

jf-common のreleasetoolsは使わないようにdevice.mk(jf-common.mk)を書き換える。

kernelは昔作ったものを使用、device関連はlineageos、vendorはJDCTeam

$ git clone -b lineage-15.1 --single-branch https://github.com/solarisintel/android_kernel_samsung_jf.git
$ git clone -b lineage-15.1 --single-branch https://github.com/LineageOS/android_device_samsung_jf-common.git
$ git clone -b lineage-15.1 --single-branch https://github.com/LineageOS/android_device_samsung_qcom-common.git
$ git clone -b lineage-15.1 --single-branch https://github.com/LineageOS/android_device_samsung_jfltevzw.git
$ git clone -b opt-cm-15.1 --single-branch  https://github.com/JDCTeam/proprietary_vendor_samsung.git

device/samsung/jfltevzwはリネームしてjfltedcmにし、デバイス名もjfltedcmに変更する。

後はビルドに必要なAndroidProducts.mkやvendorsetup.shとか作成、修正しておく

ダウンロードしたファイルの中のAndroid.mkの中に jfltevzw,jflteattなどデバイス名で判定している箇所があるのでjfltedcmを追加しておく。

メモ)proprietaryのbinファイルが/system/binから/system/vendor/binに変更されている。

8から変更された仕様

system/binからsystem/vendor/binに変更された場合、init.rcとsepolicyの書き換えが必要

device/qcom/sepolicy配下のfile_contextsとrootdir/etc/init.qcom.rcを書き換える

commonのfile_contextsは、/(vendor|system/vendor)/bin/netmgrd とvendor指定になっているものはそのままでいいが一部が/system/binとなっているので書き換える(or指定の方が都合がいいのでその形に変更する)

device/qcom/sepolicy/msm8960/file_contexts

/(system|system/vendor)/bin/thermald
/(system|system/vendor)/bin/thermal-engine
/(system|system/vendor)/bin/qcks
/(system|system/vendor)/bin/efks
/(system|system/vendor)/bin/DR_AP_Service

device/samsung/jf-common/rootdir/etc/init.qcom.rcを修正する。(system/bin から/system/vendor/binへ)

一部/system/bin/macloaderのようなproprietaryでない、ソースビルドするものはそのままにしておく

vendor/samsung/jf-common/jf-common-vendor-blobs.mkはマルチキャリア対応している。

不要なのでgsmだけ残すように、またpathも書き換える (一部のみ記載)

- vendor/samsung/jf-common/proprietary/rild/gsm/vendor/bin/efsks:system/rild/gsm/vendor/bin/efsks \
- vendor/samsung/jf-common/proprietary/rild/gsm/vendor/bin/ks:system/rild/gsm/vendor/bin/ks \
- vendor/samsung/jf-common/proprietary/rild/gsm/vendor/bin/qcks:system/rild/gsm/vendor/bin/qcks \
....
+ vendor/samsung/jf-common/proprietary/rild/gsm/vendor/bin/efsks:system/vendor/bin/efsks \
+ vendor/samsung/jf-common/proprietary/rild/gsm/vendor/bin/ks:system/vendor/bin/ks \
+ vendor/samsung/jf-common/proprietary/rild/gsm/vendor/bin/qcks:system/vendor/bin/qcks \

system.propの変更も必要

rild.libpath=/system/vendor/lib/libril-qc-qmi-1.so

vzw版はCDMA用なのでWCDMA用にoverlay/frameworks/base/core/res/res/values/config.xmlやCarrierConfigのxmlなどoverlay配下のファイルを書き換える必要がある。記述は省略。

メモ)カーネルのdefconfig

defconfigはlineageos_jf_defconfig, jf_dcm_defconfig, selinux_defconfigをマージする

マージしたファイルをlineageos_jfdcm_defconfigで保存しておき、BoardConfig.mkのdefconfig指定はこのファイル名にしておく

メモ)64ビットBinder

カーネルのdefconfigを確認

CONFIG_ANDROID_BINDER_IPC=y
# CONFIG_ANDROID_BINDER_IPC_32BIT is not set
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"

binderは32ビットを外しているので、BoardConfig.mkに以下を追加

TARGET_USES_64_BIT_BINDER := true

メモ)リカバリーのLZMA圧縮

カーネルのdefconfigを確認

# CONFIG_KERNEL_GZIP is not set
# CONFIG_KERNEL_LZMA is not set
CONFIG_KERNEL_XZ=y
....
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
CONFIG_RD_LZMA=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set

カーネル本体の圧縮はXZ, RAMDISKGZIPLZMA。device.mk, BoardConfigCommon.mkの中にLZMAの記述があるが、これはLineageOSでは実装されているが、crDroidでは対応されていないと思う。

CONFIG_KERNEL_GZIP=yにするとリカバリパーティションがサイズオーバーになる。 gzipの方が起動が早くなるし、リカバリは使わないので、適当にサイズを書き換えておく

#BOARD_RECOVERYIMAGE_PARTITION_SIZE := 10485760
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 20485760

ビルドで無視されるパラメータ

jf-common/twrp.mk:
  LZMA_RAMDISK_TARGETS := recovery

jf-common/BoardConfigCommon.mk:
  LZMA_RAMDISK_TARGETS := recovery

メモ)selinux

sepolicyが不十分で起動に失敗するのを避けるため、 BOARD_KERNEL_CMDLINE に androidboot.selinux=permissiveを追加する

BoardConfig.mk

BOARD_KERNEL_CMDLINE := androidboot.hardware=qcom user_debug=31 zcache msm_rtb.filter=0x3F ehci-hcd.park=3 androidboot.selinux=permissive

メモ) hardware/samsung のソース

hardware/samsungは crdroidのブランチlineage-15.0を使う

$ git clone -b lineage-15.0 --single-branch https://github.com/crdroidandroid/android_hardware_samsung.git

hardware/samsung/ril配下でビルドに失敗している、ログのライブラリが足りない。 hardware/samsung/ril/libsecril-client/Android.mk

@@ -11,7 +11,6 @@
     libutils \
     libbinder \
     libcutils \
+    liblog \
     libhardware_legacy

メモ)初回起動時からadbデバッグを有効にする

以下をdevice.mkに加える system_prop_debug.mk

PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
    ro.secure=0 \
    ro.adb.secure=0 \
    ro.debuggable=1 \
    persist.service.adb.enable=1

device.mk

# Include debugging props
$(call inherit-product, device/samsung/jfltedcm/system_prop_debug.mk)

メモ) adb が使えない

カーネルのadbドライバは古いバージョンのまま system/core/adb/Android.mkをみて以下をBoardConfig.mkに入れる

TARGET_USES_LEGACY_ADB_INTERFACE := true

これで初回ブートした時にadbが使えるようになる、しかしまだ画面は表示されない。 ブートアニメーションも出ない、しばらく置いておくとリブートする

この後は、logcatのエラーログを見ながら修正していく

メモ) logcatをみるとrilの動作にlibstlport.soが必要とのメッセージ

$ git clone -b lineage-15.1 --single-branch https://github.com/LineageOS/android_external_stlport.git

device.mk に追記

# external/stlport
PRODUCT_PACKAGES += libstlport

メモ) manifest.xmlから lightを削除

system_server: Waited one second for android.hardware.light@2.0::ILight/default. 
 Waiting another...

とループとなっているため。

メモ) manifest.xmlから vibratorを削除

 Waited one second for android.hardware.vibrator@1.0::IVibrator/default. 
 Waiting another...

とループとなっているため。

メモ) manifest.xmlwifiは1.1ではなくて1.0に変更

8.0では/hardware/interfaces/wifiをみると1.0しかない

    <hal format="hidl">
        <name>android.hardware.wifi</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IWifi</name>
            <instance>default</instance>
        </interface>

メモ) manifest.xmlのradioは1.1ではなくて1.0に変更

8.0では/hardware/interfaces/radioをみると1.0しかない

1スロットだけの記述に変更する

   <hal format="hidl">
        <name>android.hardware.radio</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IRadio</name>
            <instance>slot1</instance>
        </interface>
        <interface>
            <name>ISap</name>
            <instance>slot1</instance>
        </interface>
    </hal>
    <hal format="hidl">
        <name>android.hardware.radio.deprecated</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IOemHook</name>
            <instance>slot1</instance>
        </interface>
    </hal>

メモ)logcatでlibaudiopolicymanager.soがないエラーが出る

F libc    : CANNOT LINK EXECUTABLE "/system/bin/audioserver": library "libaudiopolicymanager.so" not found

確かにout/.../system 配下にlibaudiopolicymanager.soがない。

frameworks/av/services/audiopolicy/Android.mk のソースをみる。

以下の判定でUSE_CUSTOM_AUDIO_POLICYを無効にする必要があることが分かる

Android.mk

ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
...
LOCAL_MODULE:= libaudiopolicymanager
...

BoardConfigCommon.mk

BOARD_HAVE_SAMSUNG_CSDCLIENT := true
BOARD_USES_ALSA_AUDIO := true
-USE_CUSTOM_AUDIO_POLICY := 1
+#USE_CUSTOM_AUDIO_POLICY := 1
USE_LEGACY_LOCAL_AUDIO_HAL := true

メモ)rildでril_service_nameがないエラーが出る

F libc    : CANNOT LINK EXECUTABLE "/vendor/bin/hw/rild": cannot locate symbol "ril_service_name" referenced by "/system/vendor/bin/hw/rild"...

hardware/ril/rild/rild.cをcustomRom氏のlineage-15.1の参考に書き換える

$ git clone -b lineage-15.1 --single-branch https://github.com/CustomROMs/android_hardware_ril.git

QCOM_HARDWAREを入れて呼び出さないようにする

hardware/ril/rild/rild.c

...
#ifdef QCOM_HARDWARE
extern char ril_service_name_base[MAX_SERVICE_NAME_LENGTH];
extern char ril_service_name[MAX_SERVICE_NAME_LENGTH];
#endif
...
#ifdef QCOM_HARDWARE
    if (clientId == NULL) {
        clientId = "0";
    } else if (atoi(clientId) >= MAX_RILDS) {
        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
        exit(0);
    }
    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        strncpy(ril_service_name, ril_service_name_base, MAX_SERVICE_NAME_LENGTH);
        strncat(ril_service_name, clientId, MAX_SERVICE_NAME_LENGTH);
        RIL_setServiceName(ril_service_name);
    }
#endif
...
#ifdef QCOM_HARDWARE
    rilArgv[argc++] = "-c";
    rilArgv[argc++] = (char*)clientId;
    RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);
#endif

メモ)logcatでsurfaceflingerのエラーが出る

 I SurfaceFlinger: Client API: OpenGL_ES
 I SurfaceFlinger: EGLSurface: 8-8-8-8, config=0x5
 W Adreno-EGL: <qeglDrvAPI_eglGetConfigAttrib:607>: EGL_BAD_ATTRIBUTE
 I vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/hw/gralloc.default.so from the current namespace instead.
 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 30157 (surfaceflinger)

ログをよくみるとファイルがgralloc.default.soになっている。

system/lib/hw または system/vendor/lib/hw 配下に gralloc.msm8960.so がない

BoardConfigCommon.mk のTARGET_BOARD_PLATFORMが

# Platform
TARGET_BOARD_PLATFORM := MSM8960

と大文字になっており、大文字と小文字では、生成されるものが違うようである。

MSM8960で定義するとgralloc.msm8960.soやlibcopybit.msm8960.soなどが生成されない。

msm8960で定義すると hardware/samsung/liblights とhardware/qcom/display-caf/msm8960/liblightsで両方同じ記述があるというエラーになる。

hardware/qcom/display-caf/msm8960/Android.mkをみていくと

ifneq ($(TARGET_PROVIDES_LIBLIGHT),true)
display-hals += liblight
endif

とあって、BoardConfig.mkに以下を追加するとビルドしないようになっている

TARGET_PROVIDES_LIBLIGHT := true

そのためか、device.mkではわざと大文字(lights.MSM8960)にしていると思われる

したがって deviceの中に hardware/qcom/display-caf/msm8960/liblight をコピーして

BoardConfig.mk

# Platform
TARGET_BOARD_PLATFORM := msm8960
... 
TARGET_PROVIDES_LIBLIGHT := true

として、device/samsung/jf-common/liblight/Android.mkは以下のように書き換えて

LOCAL_MODULE := lights.msm8960

device.mkはmsm8960と小文字にしてビルドする

# Lights
PRODUCT_PACKAGES += \
    android.hardware.light@2.0-impl \
    lights.msm8960

メモ)ブート時のアニメーションは再生されたが、途中でリブートする

I zygote  : Thread[1,tid=3118,Native,Thread*=0xa7410000,peer=0x12c01c90,"main"] recursive attempt to load library "/system/lib/libmedia_jni.so"

 F MediaProfiles: frameworks/av/media/libmedia/MediaProfiles.cpp:329 CHECK(quality != -1) failed

MediaProfiles.cppで失敗しているらしい。原因はmediaプロファイルのファイルか?

media_codecs_google_xxx.xmlが原因だった。

正常に動くROMから持ってきて入れ替える

frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml 
frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml
frameworks/av/media/libstagefright/data/media_codecs_google_video.xml

これでようやく起動して画面が使える状態になった。

メモ)画面が暗い

画面が暗い=バックライトの光が少ない

hardware/qcom/display-caf/msm8960/liblightを使ったため

hardware/samsung/liblights を使って再ビルドする やり方は、qcom/display-caf/msm8960/liblightと同じ。

hardware/samsung/liblightsは、

・ボタンのバックライト処理のコードがある

samsung_lights.hを用意する必要がある

samsung_lights.hは、deivce/samsung/jf-common/includeにあった。

モジュール名が重複した状態でビルドしなおすときは以下を行っていた方がよい

生成したsystemディレクトリを削除

$ rm -rf out/target/product/jfltedcm/system 

out/target/product/jfltedcm/obj/SHARED_LIBRARIES/の  該当モジュールの以下のディレクトリを丸ごと削除しておく

$ rm  -rf out/.../lights.msm8960_intermediates 
$ rm  -rf out/.../lights.MSM8960_intermediates 

確認すると、hardware/samsung/liblightsが正解だった。

メモ)バックライトがOFFになってから電源ボタンを押しても画面が復旧しない

カーネルが古いため、system/core/libsuspend に手を入れる必要がある

コード量が多いのでコードは書かず、ファイル名のみ、 省略。

patch ./system/core/libsuspend/Android.bp
patch ./system/core/libsuspend/autosuspend.c
newfile ./system/core/libsuspend/autosuspend_earlysuspend.c

メモ)wifiselinuxのエラーがある

I wifi@1.0-servic: type=1400 audit(0.0:211): avc: denied { read } for name=".wifiver.info" dev="mmcblk0p29" ino=13 scontext=u:r:hal_wifi_default:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=1
I WifiScanningService: wifi driver unloaded

sepolicy/hal_wifi_default.teを作成

r_dir_file(hal_wifi_default, wifi_efs_file)

allow hal_wifi_default efs_file:dir search;
allow hal_wifi_default system_data_file:file r_file_perms;

メモ)config.xmlの設定、以下をoverlay以下にフォルダ付きでコピー、中身を書き換える

frameworks/base/core/res/res/values/cr_config.xml
frameworks/base/core/res/res/values/config.xml
lineage-sdk/lineage/res/res/values/config.xml

残念ながらWakeHomeKey関連がない。

メモ)wifiがONにならない。

以下をdevice.mkに入れたらONになった。APにつながった。

# Wifi
PRODUCT_PACKAGES += \
    android.hardware.wifi.supplicant@1.0 \
    libwpa_client \
    wificond

メモ) powerモジュールを入れる

hardware/samsung/powerを使うには、Android.mkを見ると TARGET_POWERHAL_VARIANT := samsung をBoardConfig.mkに入れておけばOKらしい

入れたら以下のログエラーが出ている

$ logcat | grep 'SamsungPowerHAL'
E SamsungPowerHAL: Error opening /sys/class/input/input3/enabled: No such file or directory
E SamsungPowerHAL: Error opening /sys/devices/system/cpu/cpu0/cpufreq/interactive/io_is_busy: No such file or directory
E SamsungPowerHAL: Error opening /sys/devices/system/cpu/cpu4/cpufreq/interactive/io_is_busy: No such file or directory

複数コアに対応していないカーネルだった。

もう1つのモジュール device/qcom/common/power を使ってみる

$ git clone -b lineage-15.1 --single-branch https://github.com/LineageOS/android_device_qcom_common.git

BoardConfig.mk

# Power hardware/samsung
# TARGET_POWERHAL_VARIANT := samsung

# Power device/qcom/common/power
TARGET_POWERHAL_VARIANT := qcom

device.mk

# Power
PRODUCT_PACKAGES += \
    android.hardware.power@1.0-impl \
    power.msm8960

今までのファイルを削除する

$ rm out/target/product/jfltedcm/system/lib/hw/power.msm8960.so
$ rm -rf out/target/product/jfltedcm/obj/SHARED_LIBRARIES/power.msm8960_intermediates

ビルド後 生成されていることを確認する

$ find out/target/product/jfltedcm/system -name '*power*'
out/target/product/jfltedcm/system/vendor/lib/hw/power.msm8960.so
$ logcat | grep 'QCOM PowerHAL'
E QCOM PowerHAL: Unable to open prefetcher: dlopen failed: library "libqti-iop-client.so" not foundE QCOM PowerHAL: Failed to get prefetcher handle.
E QCOM PowerHAL: Unable to open prefetcher: dlopen failed: library "libqti-iop-client.so" not foundE QCOM PowerHAL: Failed to get prefetcher handle.
D QCOM PowerHAL: power_open: enter; name=power

オリジナルのままではダメらしい、手直し必要、power.default.soで我慢するか。