Sebagai bagian dari persyaratan kernel modul yang diperkenalkan di Android 8.0, semua kernel system-on-chip (SoC) harus mendukung modul kernel yang dapat dimuat.
Opsi konfigurasi kernel
Untuk mendukung modul kernel yang dapat dimuat, android-base.config di semua kernel umum menyertakan opsi konfigurasi kernel berikut (atau yang setara dengan versi kernelnya):
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
Semua kernel perangkat harus mengaktifkan opsi ini. Modul kernel juga harus mendukung penghapusan muatan dan pemuatan ulang jika memungkinkan.
Penandatanganan modul
Penandatanganan modul tidak didukung untuk modul vendor GKI. Pada perangkat yang diperlukan untuk
mendukung booting terverifikasi, Android mewajibkan modul kernel berada di partisi
yang mengaktifkan dm-verity. Dengan demikian, Anda tidak perlu menandatangani setiap
modul untuk keasliannya.
Android 13 memperkenalkan konsep modul GKI. Modul GKI menggunakan infrastruktur penandatanganan waktu build kernel
untuk membedakan antara GKI dan modul lainnya 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 fragmen konfigurasi
kernel.
Lokasi file
Meskipun Android 7.x dan yang lebih rendah tidak mewajibkan modul kernel (dan menyertakan
dukungan untuk insmod
dan rmmod
), Android 8.x dan
yang lebih tinggi merekomendasikan penggunaan modul kernel dalam ekosistem. Tabel
berikut 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 booting Android, modul kernel juga dapat dikategorikan berdasarkan pemiliknya (vendor SoC atau ODM). Jika modul kernel sedang digunakan, persyaratan untuk penempatannya dalam sistem file adalah sebagai berikut:
- Semua kernel harus memiliki dukungan bawaan untuk mem-booting dan memasang partisi.
- Modul kernel harus dimuat dari partisi hanya baca.
- Untuk perangkat yang diwajibkan untuk memiliki booting terverifikasi, modul kernel harus dimuat dari partisi terverifikasi.
- Modul kernel tidak boleh berada di
/system
. - Modul GKI yang diperlukan 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 mode Android penuh atau
Pengisi daya harus berada di
/vendor/lib/modules
. - Jika partisi ODM ada, modul kernel dari ODM yang diperlukan
untuk mode Android atau Pengisi Daya penuh harus berada di
/odm/lib/modules
. Jika tidak, modul ini harus berada di/vendor/lib/modules
. - Modul kernel dari vendor SoC dan ODM yang diperlukan untuk mode
Pemulihan harus berada di
ramfs
pemulihan di/lib/modules
. - Modul kernel yang diperlukan untuk mode Pemulihan dan mode Android atau
Pengisi Daya penuh harus ada di
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 hanya berada
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 lama, partisi /vendor
dan /odm
tidak dipasang lebih awal. Di Android 8.x dan yang lebih tinggi,
untuk memungkinkan pemuatan modul dari partisi ini, ketentuan telah
dibuat untuk memasang partisi lebih awal untuk
perangkat non-A/B dan A/B. Tindakan ini juga
memastikan partisi dipasang dalam mode Android dan Pengisi Daya.
Dukungan sistem build Android
Di BoardConfig.mk
, build Android menentukan
variabel BOARD_VENDOR_KERNEL_MODULES
yang memberikan daftar lengkap
modul kernel yang ditujukan untuk image vendor. Modul yang tercantum dalam
variabel ini disalin ke dalam 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 bawaan modul kernel vendor dipetakan ke build Android di lokasi yang tercantum di atas.
Image pemulihan dapat berisi subset modul vendor. Build
Android menentukan variabel BOARD_RECOVERY_KERNEL_MODULES
untuk
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 membuat
file modules.dep
yang diperlukan di /vendor/lib/modules
dan /lib/modules
(recovery ramfs
).
Pemuatan dan pembuatan versi modul
Muat semua modul kernel dalam satu kali operasi dari init.rc*
dengan memanggil
modprobe -a
. Hal ini menghindari overhead inisialisasi berulang
lingkungan runtime C untuk biner modprobe
. 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 kernel harus dikompilasi dengan kernel yang akan digunakan modul tersebut (jika tidak, kernel akan menolak memuat modul).
CONFIG_MODVERSIONS
memberikan solusi dengan mendeteksi kerusakan
di antarmuka biner aplikasi (ABI). Fitur ini menghitung nilai cyclic redundancy check (CRC) untuk prototipe setiap simbol yang diekspor di kernel dan menyimpan nilai sebagai bagian dari kernel; untuk simbol yang digunakan oleh modul kernel, nilai juga disimpan dalam modul kernel. Saat
modul dimuat, nilai untuk simbol yang digunakan oleh modul akan dibandingkan
dengan nilai di kernel. Jika nilainya cocok, modul akan dimuat;
jika tidak, pemuatan akan gagal.
Untuk mengaktifkan update image kernel secara terpisah dari image vendor,
aktifkan CONFIG_MODVERSIONS
. Tindakan ini memungkinkan update kecil pada kernel (seperti perbaikan bug dari LTS) dilakukan sekaligus mempertahankan kompatibilitas dengan modul kernel yang ada dalam image vendor. Namun,
CONFIG_MODVERSIONS
tidak memperbaiki kerusakan ABI dengan sendirinya. Jika prototipe simbol yang diekspor di kernel berubah, baik karena modifikasi sumber atau karena konfigurasi kernel berubah, hal ini akan merusak kompatibilitas dengan modul kernel yang menggunakan simbol tersebut. Dalam kasus tersebut,
modul kernel harus dikompilasi ulang.
Misalnya, struktur task_struct
di kernel (ditentukan dalam
include/linux/sched.h
) berisi banyak kolom yang disertakan secara kondisional
bergantung pada konfigurasi kernel. Kolom sched_info
hanya ada jika CONFIG_SCHED_INFO
diaktifkan (yang
terjadi saat CONFIG_SCHEDSTATS
atau
CONFIG_TASK_DELAY_ACCT
diaktifkan). Jika opsi konfigurasi
ini mengubah status, tata letak struktur task_struct
akan berubah dan antarmuka apa pun yang diekspor dari kernel yang menggunakan
task_struct
akan diubah (misalnya,
set_cpus_allowed_ptr
di kernel/sched/core.c
).
Kompatibilitas dengan modul kernel yang dikompilasi sebelumnya yang menggunakan
antarmuka ini akan rusak, sehingga modul tersebut harus dibuat ulang dengan konfigurasi kernel
baru.
Untuk mengetahui detail selengkapnya tentang CONFIG_MODVERSIONS
, lihat
dokumentasi di hierarki kernel di
Documentation/kbuild/modules.rst
.