Membangun kernel

Halaman ini menjelaskan proses pembuatan kernel kustom untuk perangkat Android. Petunjuk ini memandu Anda melalui proses pemilihan sumber yang tepat, membangun kernel, dan menyematkan hasilnya ke dalam image sistem yang dibangun dari Proyek Open Source Android (AOSP).

Anda dapat memperoleh sumber kernel terbaru menggunakan Repo; build-nya tanpa konfigurasi lebih lanjut dengan menjalankan build/build.sh dari root checkout sumber Anda.

Mendownload sumber dan alat build

Untuk kernel terbaru, gunakan repo untuk mendownload sumber, toolchain, dan skrip build. Beberapa kernel (misalnya, kernel Pixel 3) memerlukan sumber dari beberapa repositori git, sedangkan kernel lainnya (misalnya, kernel umum) hanya memerlukan satu sumber. Penggunaan pendekatan repo memastikan penyiapan direktori sumber yang benar.

Download sumber untuk cabang yang sesuai:

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

Untuk daftar cabang repo (BRANCH) yang dapat digunakan dengan perintah `repo init` sebelumnya, lihat Cabang kernel dan sistem build-nya.

Untuk mengetahui detail tentang cara mendownload dan mengompilasi kernel untuk perangkat Pixel, lihat Mem-build Kernel Pixel.

Membangun kernel

Membangun dengan Bazel (Kleaf)

Android 13 memperkenalkan kernel build dengan Bazel.

Untuk membuat distribusi kernel GKI untuk arsitektur aarch64, lihat cabang Android Common Kernel tidak lebih awal dari Android 13, lalu jalankan perintah berikut:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

Setelah itu, biner kernel, modul, dan image yang sesuai akan berada di direktori $DIST_DIR. Jika --destdir tidak ditentukan, lihat output perintah untuk lokasi artefak. Untuk mengetahui detailnya, lihat dokumentasi tentang AOSP.

Mem-build dengan build.sh (lama)

Untuk cabang di atau di bawah Android 12, ATAU cabang tanpa Kleaf:

build/build.sh

Biner kernel, modul, dan image yang sesuai berada di direktori out/BRANCH/dist.

Membangun modul vendor untuk perangkat virtual

Android 13 memperkenalkan kernel build dengan Bazel (Kleaf), yang menggantikan build.sh.

Untuk membuat distribusi modul virtual_device, jalankan:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]

Untuk mengetahui detail selengkapnya tentang mem-build kernel Android dengan Bazel, lihat. Kleaf - Mem-build Kernel Android dengan Bazel.

Untuk mengetahui detail dukungan Kleaf untuk setiap arsitektur, lihat Dukungan Kleaf untuk perangkat dan kernel.

Mem-build modul vendor untuk perangkat virtual dengan build.sh (lama)

Di Android 12, Sotong dan Ikan Mas berkumpul, sehingga memiliki kernel yang sama: virtual_device. Untuk mem-build modul kernel tersebut, gunakan konfigurasi build ini:

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh

Android 11 memperkenalkan GKI, yang memisahkan kernel menjadi image kernel yang dikelola Google dan modul yang dikelola vendor, yang di-build secara terpisah.

Contoh ini menunjukkan konfigurasi image kernel:

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

Contoh ini menunjukkan konfigurasi modul (Cuttlefish dan Emulator):

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

Menjalankan kernel

Ada beberapa cara untuk menjalankan kernel yang dibuat secara kustom. Berikut adalah cara yang diketahui cocok untuk berbagai skenario pengembangan.

Menyematkan ke build image Android

Salin Image.lz4-dtb ke lokasi biner kernel masing-masing dalam hierarki AOSP dan build ulang image booting.

Atau, tentukan variabel TARGET_PREBUILT_KERNEL saat menggunakan make bootimage (atau command line make lainnya yang mem-build image booting). Variabel ini didukung oleh semua perangkat karena disiapkan melalui device/common/populate-new-device.sh. Contoh:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Mem-flash dan mem-boot kernel dengan fastboot

Perangkat terbaru memiliki ekstensi bootloader untuk menyederhanakan proses pembuatan dan booting image booting.

Untuk mem-booting kernel tanpa melakukan flash:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Dengan menggunakan metode ini, kernel tidak benar-benar di-flash, dan tidak akan tetap ada saat mulai ulang.

Menjalankan kernel di Cuttlefish

Anda dapat menjalankan kernel dalam arsitektur pilihan Anda di perangkat Cuttlefish.

Untuk mem-booting perangkat Cuttlefish dengan kumpulan artefak kernel tertentu, jalankan perintah cvd create dengan artefak kernel target sebagai parameter. Contoh perintah berikut menggunakan artefak kernel untuk target arm64 dari manifes kernel common-android14-6.1.

cvd create \
    -kernel_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/Image \
    -initramfs_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/initramfs.img

Untuk informasi selengkapnya, lihat Mengembangkan kernel di Cuttlefish.

Menyesuaikan build kernel

Untuk menyesuaikan build kernel untuk build Kleaf, lihat dokumentasi Kleaf.

Menyesuaikan build kernel dengan build.sh (lama)

Untuk build/build.sh, proses dan hasil build dapat dipengaruhi oleh variabel lingkungan. Sebagian besar bersifat opsional dan setiap cabang kernel harus dilengkapi dengan konfigurasi default yang tepat. Yang paling sering digunakan tercantum di sini. Untuk daftar lengkap (dan terbaru), lihat build/build.sh.

Variabel lingkungan Deskripsi Contoh
BUILD_CONFIG File konfigurasi build dari tempat Anda melakukan inisialisasi lingkungan build. Lokasi harus ditentukan secara relatif terhadap direktori root Repo. Default-nya adalah build.config.
Wajib untuk kernel umum.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Mengganti compiler yang akan digunakan. Kembali ke compiler default yang ditentukan oleh build.config. CC=clang
DIST_DIR Direktori output dasar untuk distribusi kernel. DIST_DIR=/path/to/my/dist
OUT_DIR Direktori output dasar untuk build kernel. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG Lewati make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER Lewati make mrproper SKIP_MRPROPER=1

Konfigurasi kernel kustom untuk build lokal

Di Android 14 dan yang lebih baru, Anda dapat menggunakan fragmen defconfig untuk menyesuaikan konfigurasi kernel. lihat dokumentasi Kleaf tentang fragmen defconfig.

Konfigurasi kernel kustom untuk build lokal dengan konfigurasi build (lama)

Di Android 13 dan yang lebih lama, lihat hal berikut.

Jika Anda perlu mengalihkan opsi konfigurasi kernel secara rutin, misalnya, saat mengerjakan fitur, atau jika Anda memerlukan opsi yang ditetapkan untuk tujuan pengembangan, Anda dapat mencapai fleksibilitas tersebut dengan mempertahankan modifikasi atau salinan lokal dari konfigurasi build.

Tetapkan variabel POST_DEFCONFIG_CMDS ke pernyataan yang dievaluasi tepat setelah langkah make defconfig biasa selesai. Karena file build.config bersumber ke dalam lingkungan build, fungsi yang ditentukan dalam build.config dapat dipanggil sebagai bagian dari perintah post-defconfig.

Contoh umum adalah menonaktifkan link time optimization (LTO) untuk kernel crosshatch selama pengembangan. Meskipun LTO bermanfaat untuk kernel yang dirilis, overhead pada waktu build dapat menjadi signifikan. Cuplikan berikut yang ditambahkan ke build.config lokal akan menonaktifkan LTO secara terus-menerus saat menggunakan build/build.sh.

POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
    ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
         -d LTO \
         -d LTO_CLANG \
         -d CFI \
         -d CFI_PERMISSIVE \
         -d CFI_CLANG
    (cd ${OUT_DIR} && \
     make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}

Mengidentifikasi versi kernel

Anda dapat mengidentifikasi versi yang benar untuk di-build dari dua sumber: hierarki AOSP dan image sistem.

Versi kernel dari hierarki AOSP

Hierarki AOSP berisi versi kernel bawaan. Log git menampilkan versi yang benar sebagai bagian dari pesan commit:

cd $AOSP/device/VENDOR/NAME
git log --max-count=1

Jika versi kernel tidak tercantum dalam log git, dapatkan dari image sistem, seperti yang dijelaskan di bawah.

Versi kernel dari image sistem

Untuk menentukan versi kernel yang digunakan dalam image sistem, jalankan perintah berikut terhadap file kernel:

file kernel

Untuk file Image.lz4-dtb, jalankan:

grep -a 'Linux version' Image.lz4-dtb

Mem-build image booting

Anda dapat mem-build image booting menggunakan lingkungan build kernel.

Membuat boot image untuk perangkat dengan init_boot

Untuk perangkat dengan partisi init_boot, image booting dibuat bersama dengan kernel. Gambar initramfs tidak disematkan dalam image booting.

Misalnya, dengan Kleaf, Anda dapat mem-build image booting GKI dengan:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

Dengan build/build.sh (lama), Anda dapat mem-build image booting GKI dengan:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

Gambar booting GKI terletak di $DIST_DIR.

Mem-build image booting untuk perangkat tanpa init_boot (lama)

Untuk perangkat tanpa partisi init_boot, Anda memerlukan biner ramdisk, yang dapat diperoleh dengan mendownload boot image GKI dan mengekstraknya. Semua image booting GKI dari rilis Android terkait akan berfungsi.

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4

Folder target adalah direktori tingkat teratas dari hierarki kernel (direktori kerja saat ini).

Jika Anda mengembangkan dengan AOSP utama, Anda dapat mendownload artefak build ramdisk-recovery.img dari build aosp_arm64 di ci.android.com dan menggunakannya sebagai biner ramdisk.

Jika memiliki biner ramdisk dan telah menyalinnya ke gki-ramdisk.lz4 di direktori root build kernel, Anda dapat membuat image booting dengan menjalankan:

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

Jika Anda menggunakan arsitektur berbasis x86, ganti Image dengan bzImage, dan aarch64 dengan x86_64:

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

File tersebut terletak di direktori artefak $KERNEL_ROOT/out/$KERNEL_VERSION/dist.

Image booting terletak di out/<kernel branch>/dist/boot.img.