Modul kernel yang dapat dimuat

Sebagai bagian dari persyaratan kernel modul yang diperkenalkan di Android 8.0, semua {i>system-on-chip<i} (SoC) harus mendukung modul {i> kernel<i} yang dapat dimuat.

Opsi konfigurasi kernel

Untuk mendukung modul {i>kernel<i} yang dapat dimuat, android-base.config di semua kernel umum mencakup opsi kernel-config berikut (atau versi kernel-nya yang setara):

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

Semua kernel perangkat harus mengaktifkan opsi ini. Modul kernel juga harus mendukung bongkar muat dan muat ulang jika memungkinkan.

Penandatanganan modul

Penandatanganan modul tidak didukung untuk modul vendor GKI. Pada perangkat yang diperlukan untuk mendukung booting terverifikasi, Android mengharuskan modul kernel berada dalam partisi yang mengaktifkan verifikasi dm. Dengan demikian, Anda tidak perlu lagi menandatangani setiap anggota modul untuk keasliannya. Android 13 memperkenalkan konsep modul GKI. Modul GKI menggunakan waktu build kernel menandatangani infrastruktur untuk membedakan antara GKI dan modul lain pada waktu proses. Modul yang tidak ditandatangani diizinkan untuk dimuat selama hanya menggunakan simbol yang muncul di daftar yang diizinkan atau disediakan oleh modul lain yang tidak ditandatangani. Untuk memfasilitasi penandatanganan modul GKI selama build GKI menggunakan pasangan kunci waktu build kernel, Konfigurasi kernel GKI telah mengaktifkan CONFIG_MODULE_SIG_ALL=y. Untuk menghindari penandatanganan modul non-GKI selama build kernel perangkat, Anda harus menambahkan # CONFIG_MODULE_SIG_ALL is not set sebagai bagian dari konfigurasi kernel Anda fragmen.

Lokasi file

Meskipun Android 7.x dan yang lebih rendah tidak mewajibkan modul kernel (dan termasuk dukungan untuk insmod dan rmmod), Android 8.x dan lebih tinggi merekomendasikan penggunaan modul {i>kernel<i} dalam ekosistem ini. Hal berikut tabel ini menunjukkan potensi dukungan periferal khusus board yang diperlukan di tiga Mode booting Android.

Mode Booting Penyimpanan Tampilan Keypad Baterai PMIC Layar sentuh NFC, Wi-Fi,
Bluetooth
Sensor Kamera
Pemulihan
Pengisi daya
Android

Selain ketersediaan dalam mode {i>booting<i} Android, modul {i>kernel<i} juga mungkin dikategorikan berdasarkan siapa yang memilikinya (vendor SoC atau ODM). Jika modul kernel digunakan, persyaratan untuk penempatannya dalam sistem file adalah sebagai berikut ini:

  • Semua kernel harus memiliki dukungan bawaan untuk proses {i>booting<i} dan pemasangan partisi.
  • Modul kernel harus dimuat dari partisi hanya baca.
  • Untuk perangkat yang perlu memiliki {i>booting<i} yang terverifikasi, modul {i>kernel<i} harus yang dimuat dari partisi terverifikasi.
  • Modul kernel tidak boleh ditempatkan di /system.
  • Modul GKI yang dibutuhkan untuk perangkat harus dimuat dari /system/lib/modules yang merupakan link simbolis ke /system_dlkm/lib/modules.
  • Modul kernel dari vendor SoC yang diperlukan untuk Android atau Mode pengisi daya seharusnya berada di /vendor/lib/modules.
  • Jika partisi ODM ada, modul {i>kernel<i} dari ODM yang diperlukan untuk mode Pengisi daya atau Android lengkap harus berada di /odm/lib/modules. Jika tidak, modul-modul ini harus ditempatkan di /vendor/lib/modules.
  • Modul kernel dari vendor SoC dan ODM yang diperlukan untuk Pemulihan mode harus berada di ramfs pemulihan di /lib/modules.
  • Modul kernel yang diperlukan untuk mode Pemulihan dan Android penuh atau Mode pengisi daya harus ada dalam rootfs pemulihan dan partisi /vendor atau /odm (seperti yang dijelaskan di atas).
  • Modul kernel yang digunakan dalam mode Pemulihan tidak boleh bergantung pada modul yang berada hanya di /vendor atau /odm, karena partisi tersebut tidak dipasang dalam mode Pemulihan.
  • Modul kernel vendor SoC tidak boleh bergantung pada modul kernel ODM.

Di Android 7.x dan yang lebih rendah, /vendor dan /odm partisi tidak dipasang lebih awal. Di Android 8.x dan yang lebih tinggi, agar pemuatan modul dari partisi ini bisa dilakukan, ketentuan telah dibuat untuk memasang partisi lebih awal bagi perangkat non-A/B dan A/B. Hal ini juga memastikan bahwa partisi dipasang dalam mode Android dan Pengisi Daya.

Dukungan sistem build Android

Di BoardConfig.mk, build Android menentukan Variabel BOARD_VENDOR_KERNEL_MODULES yang menyediakan daftar lengkap dari modul {i>kernel<i} yang ditujukan untuk {i>image<i} vendor. Modul yang tercantum dalam variabel ini disalin ke image vendor di /lib/modules/, dan, setelah dipasang di Android, muncul di /vendor/lib/modules (sesuai dengan persyaratan di atas). Contoh konfigurasi modul kernel vendor:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_VENDOR_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko \
  $(vendor_lkm_dir)/vendor_module_c.ko

Dalam contoh ini, repositori siap pakai modul kernel vendor dipetakan ke dalam build Android di lokasi yang tercantum di atas.

Image pemulihan dapat berisi subset modul vendor. Android build mendefinisikan variabel BOARD_RECOVERY_KERNEL_MODULES untuk modul-modul ini. Contoh:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_RECOVERY_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko

Build Android akan menjalankan depmod untuk menghasilkan modules.dep file yang diperlukan di /vendor/lib/modules dan /lib/modules (recovery ramfs).

Pemuatan dan pembuatan versi modul

Memuat semua modul kernel dalam satu penerusan dari init.rc* dengan memanggil modprobe -a. Hal ini untuk menghindari overhead melakukan inisialisasi berulang lingkungan runtime C untuk biner modprobe. Tujuan Peristiwa early-init dapat diubah untuk memanggil modprobe:

on early-init
    exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...

Biasanya, modul {i>kernel<i} harus dikompilasi dengan {i>kernel<i} yang modulnya untuk digunakan (jika tidak, {i>kernel<i} menolak untuk memuat modul). CONFIG_MODVERSIONS memberikan solusi dengan mendeteksi kerusakan di antarmuka biner aplikasi (ABI). Fitur ini menghitung permintaan nilai redundansi check (CRC) untuk prototipe setiap simbol yang diekspor dalam {i>kernel<i} dan menyimpan nilainya sebagai bagian dari {i>kernel<i}; untuk simbol yang digunakan oleh modul {i>kernel<i}, nilainya juga disimpan dalam modul {i>kernel<i}. Jika dimuat, nilai untuk simbol yang digunakan oleh modul akan dibandingkan dengan yang ada di {i>kernel<i}. Jika nilainya cocok, modul akan dimuat; jika tidak, beban akan gagal.

Untuk memungkinkan pembaruan {i>kernel<i} {i>image<i} secara terpisah dari {i>image<i} vendor, mengaktifkan CONFIG_MODVERSIONS. Melakukan hal tersebut memungkinkan pembaruan kecil pada kernel (seperti perbaikan bug dari LTS) yang akan dibuat sambil mempertahankan kompatibilitas dengan modul {i>kernel<i} yang ada di image vendor. Namun, CONFIG_MODVERSIONS tidak memperbaiki kerusakan ABI dengan sendirinya. Jika dari simbol yang diekspor dalam {i>kernel<i} berubah, baik karena modifikasi sumber atau karena konfigurasi {i>kernel<i} berubah, ini merusak kompatibilitas dengan modul {i> kernel<i} yang menggunakan simbol itu. Dalam kasus tersebut, modul {i>kernel<i} harus dikompilasi ulang.

Misalnya, struktur task_struct dalam kernel (ditentukan dalam include/linux/sched.h) berisi banyak kolom secara bersyarat disertakan tergantung pada konfigurasi {i>kernel<i}. sched_info hanya ada jika CONFIG_SCHED_INFO diaktifkan (yang terjadi saat CONFIG_SCHEDSTATS atau CONFIG_TASK_DELAY_ACCT diaktifkan). Jika konfigurasi ini opsi mengubah status, tata letak struktur task_struct perubahan dan antarmuka apa pun yang diekspor dari {i>kernel<i} yang menggunakan task_struct telah diubah (misalnya, set_cpus_allowed_ptr dalam kernel/sched/core.c). Kompatibilitas dengan modul {i>kernel<i} yang telah dikompilasi sebelumnya dan menggunakan antarmuka rusak, sehingga modul-modul tersebut harus dibangun ulang dengan {i>kernel<i} baru konfigurasi Anda.

Untuk mengetahui detail selengkapnya tentang CONFIG_MODVERSIONS, lihat dokumentasi di hierarki {i>kernel<i} di Documentation/kbuild/modules.rst.