Sistem operasi Android, sama seperti turunan Linux lainnya, adalah sistem operasi open-source. Setiap sistem operasi juga dibuat dari kode program. Proses mengubah kode program menjadi hasil akhir (artifact) yang dapat dijalankan disebut sebagai building. Bila hasil build program biasa dapat dijalankan melalui shortcut atau mengetikkan perintah di CLI, lalu bagaimana dengan sistem operasi? Seperti apa caranya menjalankan sistem operasi Android dari kode program? Saya akan mencari jawaban pertanyaan tersebut dalam tulisan ini.

Untuk men-build sistem operasi Android, saya dapat mengikuti petunjuk yang ada di https://source.android.com/setup/start. Cara termudah untuk mendapatkan kode program Android adalah dengan menggunakan tool repo yang direkomendasikan. Ini adalah Python script yang sengaja dibuat untuk mempermudah pekerjaan dengan kode program Android. Saya bisa mendapatkan versi terbarunya dengan mengikuti petunjuk di https://source.android.com/setup/build/downloading. Setelah melakukan instalasi repo, saya memberikan perintah berikut ini untuk mendapatkan kode program Android 8.1.0_r74 (Oreo):

$ repo init -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r74 --depth=1

$ repo sync

Saya hanya perlu menunggu hingga seluruh proses download selesai. Ini akan memakan waktu yang cukup lama! Apa yang sedang saya download secara resmi disebut sebagai Android Open Source Project (AOSP). Setelah mendapatkan seluruh kode program AOSP, langkah berikutnya adalah men-build kode program tersebut. Biasanya CMake adalah build system yang paling umum dipakai untuk proyek C/C++ dan Maven/Gradle untuk proyek Java. Namun, AOSP memiliki build system tersendiri yang dikembangkan khusus untuk proyek tersebut yang disebut sebagai Soong. Pada dasarnya build system ini akan menyerahkan tugasnya ke Ninja.

Sebelum melakukan building, saya akan mengubah isi file build/core/build_id.mk menjadi seperti export BUILD_ID=JOCDROID. Ini untuk memastikan bahwa sistem operasi yang dijalankan nanti adalah sistem operasi yang benar. Sekarang saatnya untuk melakukan building. Sebenarnya saya bisa langsung memanggil make yang nantinya akan mendelagasikan tugasnya ke Soong. Akan tetapi, cara yang lebih mudah adalah menggunakan script bantuan envsetup.sh yang dibuat untuk mempermudah programmer dalam bekerja dengan AOSP. Saya bisa menggunakannya dengan memberikan perintah berikut ini:

$ source build/envsetup.sh

$ lunch aosp_x86-userdebug

Perintah lunch dapat dipakai untuk memilih target perangkat dan variasi sistem operasi yang hendak dibuat. Setelah perintah ini diberikan, saya akan memiliki beberapa perintah siap pakai seperti m, emulator, dan sebagainya. Jangan lupa mengerjakan kembali perintah di atas bila berpindah ke terminal baru!

Saya bisa memulai building dengan memberikan perintah:

$ export LC_ALL=C

$ m -j16

Sesuaikan nilai parameter -j dengan jumlah core CPU untuk mendapatkan kinerja terbaik. Tergantung pada CPU yang dipakai, proses pertama kali bisa berlangsung hingga satu jam lebih! Selain itu, bisa saja berakhir dengan kegagalan jika package yang dibutuhkan belum ter-install di sistem operasi. Namun, hal ini bisa diatasi cukup dengan memberikan perintah sudo apt get untuk package yang kurang.

Seperti apa file yang dihasilkan setelah proses building selesai? Saya bisa menemukannya dengan memberikan perintah berikut ini:

$ ls out/target/product/generic_x86/*.img

out/target/product/generic_x86/cache.img          out/target/product/generic_x86/system-qemu.img    out/target/product/generic_x86/userdata.img
out/target/product/generic_x86/encryptionkey.img  out/target/product/generic_x86/system.img         out/target/product/generic_x86/vendor-qemu.img
out/target/product/generic_x86/ramdisk.img        out/target/product/generic_x86/userdata-qemu.img  out/target/product/generic_x86/vendor.img

Image ini dikenal sebagai Generic System Image (GSI). Bagian yang paling penting dari file di atas adalah system.img yang mengandung segala sesuatu yang dibutuhkan oleh sistem operasi Android (belum termasuk kernel!). Untuk menjalankannya, saya bisa memberikan perintah berikut ini:

$ emulator

Tampilan Emulator

Akhirnya saya bisa melihat seperti apa sistem operasi Android yang paling murni tanpa tambahan dari OEM termasuk dari Google. Yup! AOSP tidak mengandung Google Play Services sehingga saya tidak bisa menggunakan fitur seperti Google Play. Dengan demikian, aplikasi seperti Gmail dan YouTube tidak akan bisa berjalan di AOSP.

Saya bisa memastikan bahwa ini adalah sistem operasi yang saya build dengan memeriksa build number:

Build Number

Apa yang terjadi pada saat perangkat keras pertama kali dinyalakan? Kode program dalam chip (SoC) akan dikerjakan. Sebagai contoh, di chipset Qualcomm, kode program ini disebut sebagai Primary Bootloader (PBL). Karena merupakan SoC, PBL tidak bisa dimodifikasi oleh OEM dan pengguna. PBL bertugas mempersiapkan hardware seperti memori, menyalin Secondary Bootloader (SBL) atau XBL (eXtensible Bootloader) ke memori dan menyerahkan eksekusi ke wilayah memori tersebut. Pada akhirnya, mereka akan menjalankan bootloader dari Android (ABL).

Selanjutnya, akan ada 2 kemungkinan image yang akan dikerjakan: sistem operasi recovery atau sistem operasi utama.

Bila pengguna memilih untuk masuk ke recovery mode atau baru saja terjadi OTA update, maka sistem operasi recovery akan dijalankan. Ini adalah sebuah sistem operasi yang berdiri sendiri yang berjalan tanpa adanya kehadiran sistem operasi utama. Dengan kata lain, sistem operasi recovery masih tetap akan bekerja walaupun sistem operasi utama secara tidak sengaja terhapus.

Pada kondisi normal, tentu saja sistem operasi utama yang akan dikerjakan. Secara fisik, bagian ini terletak di boot.img. File ini berisi kernel sistem operasi Android. Kernel adalah inti dari sistem operasi Linux. Pada emulator yang saya jalankan, kernel yang dipakai adalah out/target/product/generic_x86/kernel-ranchu.
Ini adalah kernel yang hanya bisa berjalan di emulator saja.

Kenapa saya tidak menjumpai file boot.img pada saat melakukan building untuk target aosp_x86-userdebug? Hal ini karena target-nya adalah emulator dimana kernel-ranchu dipakai secara langsung oleh emulator. Untuk melihat file boot.img dihasilkan sebagai output, saya bisa mencoba melakukan building untuk perangkat asli, dengan memberikan perintah seperti berikut ini:

$ lunch aosp_bullhead-userdebug

$ m -j16

Sekarang, saya akan menemukan hasil build seperti berikut ini:

$ ls out/target/product/generic_x86/*.img

out/target/product/bullhead/boot.img   out/target/product/bullhead/ramdisk-recovery.img  out/target/product/bullhead/recovery.img  out/target/product/bullhead/userdata.img
out/target/product/bullhead/cache.img  out/target/product/bullhead/ramdisk.img           out/target/product/bullhead/system.img

Baik file boot.img maupun recovery.img berisi kernel tersendiri dan bisa berjalan tanpa tergantung satu sama lainnya. Namun, pada proses boot normal, hanya file boot.img yang akan dipakai.

Setelah kernel dijalankan, ia memiliki kendali penuh untuk menentukan apa yang akan dilakukan selanjutnya. Saya bisa melihat alur eksekusi ini dengan menggunakan fasilitas Bootchart. Saya bisa mengaktifkannya dengan memberikan perintah seperti berikut ini:

$ emulator -bootchart 180 -no-snapshot

Seharusnya argumen -bootchart 180 akan secara otomatis menjalankan proses bootchart selama 2 menit. Akan tetapi, saya menemukan bahwa pada emulator yang saya pakai. Oleh sebab itu, sebagai gantinya, saya menjalankan perintah adb shell setelah emulator dijalankan dan kemudian memberikan perintah berikut ini:

$ su

$ touch /data/bootchart/enabled

$ reboot

Perintah di atas akan mengaktifkan proses bootchart yang melakukan pengumpulan data. Sambil menunggu sistem operasi Android dijalankan, saya bisa menjalankan perintah berikut ini untuk men-download tool yang dapat menghasilkan grafis berdasar data bootchart:

$ sudo apt install pybootchartgui

Setelah halaman utama Android ditampilkan di emulator, saya kemudian memberikan perintah berikut ini (melalui terminal terpisah tanpa mematikan emulator):

$ $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh

Saya akan menjumpai file bootchart.png di lokasi dimana saya memberikan perintah di atas. Tampilannya terlihat seperti pada gambar berikut ini:

Hasil Bootchart

Pada grafis di-atas, terlihat bahwa init adalah proses yang pertama kali dipanggil. Ia juga menunjukkan permulaan dari pengerjaan kode program kernel. Ini bukanlah sesuatu yang spesifik pada Android, melainkan sesuatu yang umum dan berlaku untuk seluruh sistem operasi Linux. Grafis bootchart juga memperlihatkan proses apa saja yang dibuat oleh init termasuk informasi CPU dan disk utilization pada saat proses tersebut berjalan.