W ramach wymagań jądra modułów wprowadzonych w Androidzie 8.0 wszystkie Jądra systemu SOC muszą obsługiwać możliwe do załadowania moduły jądra.
Opcje konfiguracji jądra systemu
Aby zapewnić obsługę wczytywanych modułów jądra, Plik android-base.config we wszystkich popularnych jądrach zawiera komponent następujące opcje konfiguracji jądra (lub ich odpowiedniki w wersji jądra):
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
Wszystkie jądra urządzeń muszą mieć włączone te opcje. Moduły jądra powinny obsługują wyładowywanie i ponowne ładowanie.
Podpisywanie modułu
Podpisywanie modułów nie jest obsługiwane w przypadku modułów dostawcy GKI. Na urządzeniach wymaganych do
obsługa weryfikacji podczas uruchamiania, Android wymaga, aby moduły jądra były umieszczone na partycjach.
z włączoną usługą dm-verity. Eliminuje to potrzebę podpisywania indywidualnej osoby
modułów za ich autentyczność.
W Androidzie 13 wprowadzono koncepcję modułów GKI. Moduły GKI używają czasu kompilacji jądra
infrastruktury podpisywania w celu odróżniania GKI od innych modułów w czasie działania.
Moduły niepodpisane mogą się ładować, pod warunkiem że zawierają tylko symbole znajdujące się na liście dozwolonych
lub dostarczane przez inne niepodpisane moduły.
Aby ułatwić podpisywanie modułów GKI podczas kompilacji GKI za pomocą pary kluczy czasu kompilacji jądra,
Konfiguracja jądra GKI włączyła funkcję CONFIG_MODULE_SIG_ALL=y
.
Aby uniknąć podpisywania modułów innych niż GKI podczas kompilacji jądra urządzenia, musisz dodać
# CONFIG_MODULE_SIG_ALL is not set
w ramach konfiguracji jądra
fragmenty.
Lokalizacje plików
Android 7.x i starsze nie wymagają stosowania modułów jądra
obsługa systemów insmod
i rmmod
), Androida 8.x i
zalecają korzystanie w ekosystemie z modułów jądra. Poniżej
Tabela przedstawia potencjalną obsługę konkretnej płyty peryferyjnej wymaganej przez trzy
Tryby uruchamiania Androida.
Tryb uruchamiania | Miejsce na dane | Wyświetlacz | Klawiatura | Bateria | PMIC, | Ekran dotykowy | NFC, Wi-Fi, Bluetooth |
Czujniki | Aparat |
---|---|---|---|---|---|---|---|---|---|
Odzyskanie | |||||||||
Ładowarka | |||||||||
Android |
Poza dostępnością w trybach rozruchu Androida moduły jądra mogą być również są podzielone na kategorie według tego, kto jest ich właścicielem (dostawcy układu SOC lub ODM). Jeśli moduły jądra systemu ich umiejscowienie w systemie plików następujące:
- Wszystkie jądra powinny mieć wbudowaną obsługę uruchamiania i montowania partycji.
- Moduły jądra muszą być ładowane z partycji tylko do odczytu.
- Aby urządzenia wymagały weryfikacji podczas uruchamiania, moduły jądra systemu powinny być załadowano ze zweryfikowanych partycji.
- Moduły jądra nie powinny znajdować się w regionie
/system
. - Moduły GKI wymagane przez urządzenie powinny być ładowane z
/system/lib/modules
, który jest łączem symbolicznym do:/system_dlkm/lib/modules
- Moduły jądra systemu SOC, które są wymagane do działania pełnej wersji Androida lub
Tryby ładowarki powinny znajdować się w trybie
/vendor/lib/modules
. - Jeśli istnieje partycja ODM, wymagane są moduły jądra ODM.
w trybie pełnego Androida lub ładowania należy znajdować się w
/odm/lib/modules
W przeciwnym razie moduły te powinny znajdować się w/vendor/lib/modules
- Moduły jądra systemu SoC i ODM wymagane do przywracania
tryb powinien znajdować się w sekcji odzyskiwania (
ramfs
) na/lib/modules
- Moduły jądra są wymagane zarówno w trybie odzyskiwania, jak i w wersji z pełną wersją Androida lub
Tryby ładowarki powinny być dostępne zarówno w trybie
rootfs
odzyskiwania, jak i partycję/vendor
lub/odm
(zgodnie z opisem) powyżej). - Moduły jądra używane w trybie przywracania nie powinny zależeć od modułów znajdujących się
tylko w
/vendor
lub/odm
, ponieważ te partycje nie są podłączonych w trybie odzyskiwania. - Moduły jądra dostawcy SoC nie powinny opierać się na modułach jądra ODM.
Na Androidzie 7.x i starszych: /vendor
i /odm
partycje nie są podłączone wcześnie. W Androidzie 8.x i nowszych
aby możliwe było ładowanie modułów z tych partycji, zasoby reklamowe zostały udostępnione
wczesne montowanie partycji w obu
urządzeniami innych niż A/B i A/B. To także
pozwala na zamontowanie partycji zarówno w trybie Androida, jak i w trybie ładowarki.
Obsługa systemu Android Build
W BoardConfig.mk
kompilacja Androida definiuje
Zmienna BOARD_VENDOR_KERNEL_MODULES
, która przedstawia pełną listę
modułów jądra przeznaczonych dla obrazu dostawcy. Moduły wymienione w
ta zmienna jest kopiowana do obrazu dostawcy pod adresem /lib/modules/
,
Po podłączeniu do Androida
/vendor/lib/modules
(zgodnie z powyższymi wymaganiami).
Przykładowa konfiguracja modułów jądra dostawcy:
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
W tym przykładzie gotowe repozytorium modułu jądra dostawcy jest mapowane kompilację Androida w podanej wyżej lokalizacji.
Obraz przywracania może zawierać podzbiór modułów dostawcy. Android
kompilacja definiuje zmienną BOARD_RECOVERY_KERNEL_MODULES
dla
dla tych modułów. Przykład:
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
Kompilacja Androida obsługuje uruchamianie depmod
, aby generować
wymagane pliki: modules.dep
w zasobniku /vendor/lib/modules
i /lib/modules
(recovery ramfs
).
Wczytywanie modułu i obsługa wersji
Wczytaj wszystkie moduły jądra w jednej przepustce z init.rc*
przez wywołanie
modprobe -a
Pozwala to uniknąć konieczności wielokrotnego inicjowania
w środowisku wykonawczym C dla pliku binarnego modprobe
.
Zdarzenie early-init
można zmodyfikować, aby wywoływać metodę modprobe
:
on early-init exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules module_a module_b module_c ...
Zazwyczaj moduł jądra systemu musi być skompilowany z jądrem,
z którym ma być używany (w przeciwnym razie jądro zablokuje załadowanie modułu).
CONFIG_MODVERSIONS
udostępnia obejście polegające na wykrywaniu usterek
w interfejsie binarnym aplikacji (ABI). Ta funkcja oblicza cykl
kontroli nadmiarowości (CRC) dla prototypu każdego wyeksportowanego symbolu w
ją jądra i przechowuje wartości w jego ramach; dla symboli używanych przez
, wartości są również przechowywane w module jądra. Gdy
jest wczytywany, wartości symboli używanych przez moduł są porównywane
i te w jądrze. Jeśli wartości są zgodne, moduł jest wczytywany.
w przeciwnym razie wczytywanie się nie uda.
Aby umożliwić aktualizowanie obrazu jądra niezależnie od obrazu dostawcy,
włącz funkcję CONFIG_MODVERSIONS
. Pozwoli to wprowadzić niewielkie aktualizacje
jądro (np. poprawki błędów z LTS), które należy wprowadzić przy zachowaniu zgodności
z istniejącymi modułami jądra w obrazie dostawcy. Pamiętaj jednak:
CONFIG_MODVERSIONS
samo w sobie nie naprawia błędu ABI. Jeśli
prototyp wyeksportowanego symbolu w jądrze zmienia się z powodu
ze względu na zmianę źródła lub konfigurację jądra,
narusza zgodność z modułami jądra używającymi tego symbolu. W takich przypadkach
moduł jądra systemu należy skompilować ponownie.
Na przykład struktura task_struct
w jądrze (zdefiniowana w
include/linux/sched.h
) zawiera wiele pól warunkowo
w zależności od konfiguracji jądra systemu operacyjnego. sched_info
jest dostępne tylko wtedy, gdy włączona jest opcja CONFIG_SCHED_INFO
(która
występuje, gdy CONFIG_SCHEDSTATS
lub
CONFIG_TASK_DELAY_ACCT
). Jeśli te konfiguracje
opcje zmieniają stan, układ struktury task_struct
i wszystkich wyeksportowanych interfejsów z jądra, które używają
task_struct
zostały zmienione (na przykład
set_cpus_allowed_ptr
w kernel/sched/core.c
).
Zgodność ze skompilowanymi wcześniej modułami jądra, które korzystają z tych
interfejsów ulegają awarii, co wymaga odbudowy tych modułów za pomocą nowego jądra systemu
konfiguracji.
Więcej informacji o CONFIG_MODVERSIONS
znajdziesz tutaj:
w drzewie jądra pod adresem
Documentation/kbuild/modules.rst