Pada tulisan sebelumnya, saya men-build AOSP dari kode program. Fokus utama tulisan tersebut adalah boot.img dan system.img. Kali ini, saya akan mencoba bermain dengan recovery image (recovery.img). Ini adalah sebuah sistem operasi kedua yang benar-benar terpisah dari sistem operasi utama. Untuk memasuki sistem operasi recovery, pengguna harus menggunakan kombinasi tombol tertentu pada saat perangkat pertama kali dinyalakan. Sistem operasi recovery bawaan biasanya menyediakan fasilitas yang sangat sederhana seperti menghapus seluruh data pengguna atau mengatur ulang perangkat agar kembali seperti semula.

Sebagai alternatif, saya bisa meng-install sistem operasi recovery pihak ketiga seperti TWRP yang menawarkan lebih banyak fasilitas. Pengguna yang sering melakukan instalasi custom ROM pasti tidak asing lagi dengan TWRP. Ia merupakan bagian sistem operasi OmniROM (sistem operasi turunan AOSP yang dibuat oleh komunitas). Walaupun TWRP awalnya dirancang untuk OmniROM, ia sudah menjadi standar untuk melakukan instalasi custom ROM lain seperti LineageOS. Karena sistem operasi recovery terpisah dan umumnya tidak dijalankan sehari-hari, ia bisa memiliki versi Android yang berbeda dengan sistem operasi utama. Bukan hanya itu, sistem operasi recovery juga tetap akan bekerja walaupun sistem operasi utama dihapus.

Bila perangkat yang saya pakai sudah didukung secara resmi oleh TWRP di https://twrp.me/Devices/, saya hanya perlu men-download image recovery di halaman yang tersedia. Tetapi bagaimana bila perangkat yang saya pakai tidak didukung? Sebagai contoh, saya akan menggunakan perangkat Xiaomi Mi 8 Lite dengan nama kode platina. Perangkat ini belum didukung secara resmi. Walapun tidak sulit untuk menemukan image tidak resmi yang beredar di berbagai website dan forum, cara yang lebih aman adalah dengan menghasilkan image sendiri berdasarkan kode program TWRP.

Apa yang saya butuhkan?

  • Kode program TWRP: Saya tidak akan men-build OmniROM, jadi saya akan menggunakan https://github.com/minimal-manifest-twrp sebagai daftar manifest untuk repo.
  • Kode program kernel: Ini adalah bagian yang paling open source karena kernel Linux menggunakan lisensi GPL sehingga seluruh turunan dari kernel Linux harus bersifat open source juga. Saya bisa menemukan kode program kernel untuk perangkat Mi 8 Lite di https://github.com/MiCode/Xiaomi_Kernel_OpenSource/tree/nitrogen-p-oss (untuk Android 9).
  • Device tree: Ini bagian yang paling merepotkan. Walapun saya bisa menggunakan device tree dari pihak ketiga, bila mereka menyertakan binary, saya tidak bisa memastikan apakah binary tersebut berbahaya atau tidak. Akan lebih baik bila semuanya berupa kode program atau file yang saya ekstraks sendiri dari ROM resmi. Oleh sebab itu, saya memutuskan untuk menyalin dari device tree Mi 8 (dipper) yang didukung resmi dan dapat ditemukan di https://github.com/TeamWin/android_device_xiaomi_dipper.

Saya akan mulai dengan memberikan perintah berikut ini:

$ repo init --depth=1 -u git://github.com/minimal-manifest-twrp/platform_manifest_twrp_omni.git -b twrp-9.0

Pada perintah di atas, saya menggunakan kode program TWRP yang berdasarkan OmniROM dan Android 9 (Pie). Sebagai informasi, saya sebelumnya sudah melakukan instalasi tools repo dari Google di tulisan sebelumnya.

Berikutnya, saya membuat sebuah local manifest untuk repo dengan nama seperti platina.xml di lokasi .repo/local_manifests dengan isi seperti berikut ini:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <remote name="kernel" fetch="https://github.com" revision="nitrogen-p-oss" />
    <project path="kernel/xiaomi/platina" name="MiCode/Xiaomi_Kernel_OpenSource" remote="kernel" />

    <remote name="device" fetch="https://github.com" revision="android-9.0" />
    <project path="device/xiaomi/platina" name="TeamWin/android_device_xiaomi_dipper" remote="device"/>
</manifest>

Manifest di atas akan menginstruksikan repo untuk men-download dari GitHub yang bersangkutan ke folder kernel/xiaomi/platina dan device/xiaomi/platina. Saya dapat memulai proses download dengan memberikan perintah berikut ini (sembari mempersiapkan diri untuk menunggu proses download 22,7 GB selesai):

$ . build/envsetup.sh

$ repo sync

Langkah berikutnya adalah mengubah isi device tree yang ada di folder device/xiaomi/platina. Saya bisa memulai dengan mencari kata dipper dan menggantinya dengan platina dengan menggunakan perintah berikut ini:

$ find device/xiaomi/platina -type f -exec sed -i 's/dipper/platina/g' {} +

$ find device/xiaomi/platina -type f -exec sed -i 's/MI 8/MI 8 Lite/g' {} +

$ find device/xiaomi/platina -name "*dipper*" -exec rename -v 's/dipper/platina/g' {} \;

File yang paling penting di /device/xiaomi/platina adalah BoardConfig.mk. Saya perlu melakukan beberapa pengaturan variabel di file ini.

Saya akan mulai dari konfigurasi kernel. Karena kode program kernel sudah disertakan, saya bisa menghapus variabel TARGET_PREBUILT_KERNEL dan juga file Image.gz-dtb bawaan. Saya merasa men-build sendiri kernel dari kode program lebih aman daripada memakai hasil kompilasi pihak ketiga (yang mungkin telah melakukan modifikasi kode program).

Selain itu, saya perlu menambahkan variabel yang dibutuhkan untuk kompilasi kernel seperti berikut ini:

TARGET_KERNEL_ARCH := arm64
TARGET_KERNEL_CONFIG := platina_user_defconfig
TARGET_KERNEL_CROSS_COMPILE_PREFIX := aarch64-linux-android-
TARGET_KERNEL_SOURCE := kernel/xiaomi/platina

Untuk mendapatkan nilai BOARD_KERNEL_CMDLINE, saya bisa mencontoh dari ROM resmi Mi 8 Lite yang bisa di-download di https://c.mi.com/miuidownload. File yang saya butuhkan disini adalah boot.img. Ini sebenarnya adalah file arsip yang terdiri atas:

  • bootimg.cfg
  • zImage (kernel)
  • initrd.img (ramdisk)

Untuk meng-ekstraks boot.img, saya bisa menggunakan tool abootimg dengan memberikan perintah:

$ abootimg -x boot.img

Sekarang, saya tinggal membuka file bootimg.cfg dan memeriksa nilai cmdline di-sini. Saya perlu menyalin isi cmdline ke variabel BOARD_KERNEL_CMDLINE di BoardConfig.mk seperti yang terlihat pada baris berikut ini:

BOARD_KERNEL_CMDLINE := console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 earlycon=msm_serial_dm,0xc170000 androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 sched_enable_hmp=1 sched_enable_power_aware=1 service_locator.enable=1 swiotlb=1 firmware_class.path=/vendor/firmware_mnt/image loop.max_part=7 buildvariant=user

Mi 8 menggunakan chipset Snapdragon 845 (CPU Kyro 385) dan GPU Adreno 630 sementara Mi 8 Lite menggunakan Snapdragon 660 (CPU Kyro 260) dan GPU Adreno 512. Oleh sebab itu, saya melakukan perubahan pada parameter berikut ini:

TARGET_2ND_ARCH_VARIANT := armv8-a
TARGET_2ND_CPU_ABI := arm64-v8a
TARGET_2ND_CPU_VARIANT := cortex-a53
TARGET_BOOTLOADER_BOARD_NAME := sdm660
TARGET_BOARD_PLATFORM := sdm660
TARGET_BOARD_PLATFORM_GPU := qcom-adreno512

Sekarang, saya bisa memulai proses building dengan memberikan berikut ini:

$ . build/envsetup.sh

$ lunch omni_platina-eng

$ export ALLOW_MISSING_DEPENDENCIES=true

$ mka clean && mka -j12 recoveryimage

Setelah proses building selesai, saya dapat menguji image yang dihasilkan tanpa harus melakukan instalasi dengan menggunakan perintah fastboot. Akan tetapi, sebelumnya, saya perlu masuk dulu ke dalam modus bootloader di perangkat saya. Hal ini bisa dilakukan dengan mematikan perangkat dan menahan kombinasi tombol power + volume down pada saat perangkat dinyalakan. Setelah logo “fastboot” muncul, saya kemudian memberikan perintah berikut ini:

$ fastboot boot out/target/product/platina/recovery.img

Sistem operasi TWRP yang saya build segera dijalankan. Setelah memastikan tidak ada masalah, saya kemudian melakukan instalasi secara permanen ke partisi recovery dengan memberikan perintah berikut ini:

$ fastboot flash recovery out/target/product/platina/recovery.img

Untuk menjalankan sistem operasi recovery di Mi 8 Lite, saya bisa mematikan perangkat tersebut dan menahan kombinasi tombol power dan volume up pada saat perangkat dinyalakan.