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!
croot
di terminal. Mereka biasanya bahagia dengan editor CLI seperti vim
. Hal ini sangat berbeda dengan programmer web yang sering memperdebatkan IDE
favorit mereka dan mengutamakan fasilitas seperti font dan dark mode.
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
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.
emulator
bisa menjalankan image tanpa harus membuat AVD terlebih dahulu? Hal ini karena macro lunch
secara otomatis
menambahkan ANDROID_PRODUCT_OUT
dan berbagai environment variable lainnya. emulator
akan menjalankan image di
folder ANDROID_PRODUCT_OUT
bila variabel tersebut didefinisikan. Parameter seperti -sysdir
, -system
, -vendor
,
-kernel
, -ramdisk
, -datadir
dan -data
juga dapat dipakai lebih lanjut untuk mengatur lokasi image file
yang hendak dipakai.
Saya bisa memastikan bahwa ini adalah sistem operasi yang saya build dengan memeriksa build number:
device/lge/bullhead/proprietary-blobs.txt
. Selain itu, saya juga perlu mengganti perintah lunch aosp_x86-userdebug
dengan
lunch aosp_bullhead-userdebug
.
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.
device/lge/bullhead-kernel/Image.gz-dtb
.
Bila bila saya ingin melihat kode program atau ingin megubah kode program kernel? Saya bisa mendapatkan kode program kernel untuk perangkat keras
target saya dengan mengikuti petunjuk di https://source.android.com/setup/build/building-kernels.
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.
Pada PC modern dengan UEFI (sebagai pengganti BIOS), terdapat pilihan "Secure Boot" di menu UEFI. Bila fitur ini aktif, bootloader sistem operasi yang
ter-install akan diverifikasi sebelum dikerjakan. Saya tidak akan bisa men-install OS seperti distro Linux tertentu karena bootloader mereka tidak
di-sign sehingga dianggap tidak aman. Distro modern yang populer mengatasi masalah ini dengan menggunakan shim booatloader yang
di-sign oleh Microsoft (shim-signed
atau grub-efi-amd64-signed
) sehingga bootloader mereka dianggap aman.
Android juga memiliki fasilitas serupa yang disebut dengan Verified Boot. Istilah yang umum dipakai di Android adalah perangkat memiliki bootloader terkunci (locked bootloader). Tidak seperti PC dimana saya cukup masuk ke menu UEFI dan memilih konfigurasi bersangkutan, 'kunci' bootloader di Android dapat dibuka tergantung pada kebijakan si pembuat perangkat. Sebagai contoh, membuka kunci ini di perangkat buatan Google sangat mudah. Sebaliknya, proses ini cukup merepotkan di perangkat Xiaomi karena saya harus men-download aplikasi tertentu dari Xiaomi yang hanya bisa dijalankan di Windows.
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:
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.