Ogólny obraz jądra (GKI) może nie zawierać wymaganego sterownika, który umożliwi urządzeniu zamontowanie partycji. Aby umożliwić urządzeniu montowanie partycji i kontynuowanie rozruchu, w pierwszym etapie init
zostaje ulepszony w celu wczytania modułów jądra znajdujących się na dysku RAM. Pamięć RAM jest podzielona na ogólną i pamięć RAM dla dostawcy. Moduł dostawcy jądra jest przechowywany w pamięci RAM dostawcy. Kolejność ładowania modułów jądra można skonfigurować.
Lokalizacja modułu
Pamięć RAM to system plików dla pierwszego etapu init,
oraz dla obrazu odzyskiwania/fastboot na urządzeniach A/B i wirtualnych urządzeniach A/B. Jest to initramfs
składający się z 2 archiwów cpio, które są łączone przez bootloader. Pierwsze archiwum cpio, które jest przechowywane jako ramdysk dostawcy na partycji rozruchowej dostawcy, zawiera te komponenty:
- Pierwszorzędne moduły
init
dostawcy jądra, znajdujące się w/lib/modules/
. modprobe
pliki konfiguracji znajdujące się w folderze/lib/modules/
:modules.dep
,modules.softdep
,modules.alias
,modules.options
.- Plik
modules.load
, który wskazuje, które moduły mają być wczytane podczas pierwszego etapu inicjalizacji oraz w jakiej kolejności w pliku/lib/modules/
. - Moduł dostawcy modułów jądra do przywracania danych, w przypadku urządzeń A/B i wirtualnych urządzeń A/B, w
/lib/modules/
modules.load.recovery
, który wskazuje moduły do załadowania oraz kolejność ich ładowania na urządzeniach A/B i wirtualnych urządzeniach A/B (/lib/modules
).
Drugie archiwum cpio, które jest dostarczane z GKI jako ramdysk pliku boot.img i jest stosowane na wierzchu pierwszego, zawiera first_stage_init
i biblioteki, od których jest zależne.
Wczytywanie modułu w ramach inicjalizacji pierwszego etapu
Pierwszy etap init
rozpoczyna się od odczytania plików konfiguracji modprobe z /lib/modules/
na dysku RAM. Następnie odczytuje listę modułów określoną w pliku /lib/modules/modules.load
(lub w przypadku przywracania – w pliku /lib/modules/modules.load.recovery
) i próbuje kolejno załadować każdy z nich zgodnie z konfiguracją określoną w wcześniej załadowanych plikach. Żądana kolejność może być zmieniona, aby spełnić twarde lub miękkie zależności.
Obsługa kompilacji, inicjalizacja pierwszego etapu
Aby określić moduły jądra, które mają zostać skopiowane do pliku cpio na partycji ramdysk dostawcy, wpisz je w pliku BOARD_VENDOR_RAMDISK_KERNEL_MODULES
. Kompilacja jest wykonywana depmod
na tych modułach, a wygenerowane pliki konfiguracyjne modprobe są umieszczane w pliku cpio w ramdisku dostawcy.
Kompilacja tworzy też plik modules.load
i zapisuje go w pliku cpio na dysku RAM dostawcy. Domyślnie zawiera wszystkie moduły wymienione w sekcji BOARD_VENDOR_RAMDISK_KERNEL_MODULES
. Aby zastąpić zawartość tego pliku, użyj BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
, jak pokazano w tym przykładzie:
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \ device/vendor/mydevice-kernel/first.ko \ device/vendor/mydevice-kernel/second.ko \ device/vendor/mydevice-kernel/third.ko
Obsługa kompilacji, pełny Android
Podobnie jak w przypadku Androida 10 i starszych wersji, moduły jądra wymienione w pliku BOARD_VENDOR_KERNEL_MODULES
są kopiowane przez kompilację platformy Android do partycji dostawcy w pliku /vendor/lib/modules
. Kompilacja platformy uruchamia depmod
na tych modułach i kopiuje pliki wyjściowe depmod
do partycji dostawcy w tym samym miejscu. Mechanizm wczytywania modułów jądra z /vendor
pozostaje taki sam jak w poprzednich wersjach Androida. To Ty decydujesz, kiedy i jak wczytywać te moduły, choć zwykle odbywa się to za pomocą skryptów init.rc
.
Symbole wieloznaczne i zintegrowane kompilacje jądra
Dostawcy, którzy łączą kompilację jądra urządzenia z kompilacją platformy Androida, mogą napotkać problem z użyciem wymienionych makro BOARD
do określenia modułów jądra do skopiowania na urządzenie. Jeśli sprzedawca nie chce wymieniać modułów jądra w plikach kompilacji platformy urządzenia, może użyć symbolu zastępczego ($(wildcard device/vendor/mydevice/*.ko
). Pamiętaj, że w przypadku zintegrowanej kompilacji jądra symbol zastępczy nie działa, ponieważ gdy wywoływana jest komenda make, a makro jest rozwijane w plikach make, moduły jądra nie są jeszcze kompilowane, więc makro jest puste.
Aby rozwiązać ten problem, dostawca może utworzyć archiwum ZIP z kompilacją jądra zawierającą moduły jądra, które mają być kopiowane na każdą partycję.
Ustaw ścieżkę do tego archiwum ZIP w pliku BOARD_*_KERNEL_MODULES_ARCHIVE
, gdzie *
to nazwa partycji (np. BOARD_VENDOR_KERNEL_MODULES_ARCHIVE
). Kompilacja platformy Android wyodrębni to archiwum ZIP w odpowiednim miejscu i uruchomi depmod
na modułach.
Archiwum ZIP modułu jądra powinno mieć regułę make, która zapewnia, że platforma build może wygenerować archiwum w razie potrzeby.
Odzyskiwanie
W poprzednich wersjach Androida moduły jądra wymagane do przywracania były określone w BOARD_RECOVERY_KERNEL_MODULES
. W Androidzie 12 moduły jądra wymagane do przywracania są nadal określane za pomocą tego makra. Jednak moduły jądra odzyskiwania są kopiowane do pliku cpio w pamięci RAM dostawcy, a nie do pliku cpio w pamięci RAM. Domyślnie wszystkie moduły jądra wymienione w BOARD_RECOVERY_KERNEL_MODULES
są ładowane podczas pierwszego etapu init
. Jeśli chcesz załadować tylko podzbiór tych modułów, określ zawartość tego podzbioru w sekcji BOARD_RECOVERY_KERNEL_MODULES_LOAD
.
Powiązana dokumentacja
Informacje o tworzeniu partycji rozruchowej dostawcy (która zawiera wspomniany na tej stronie ramdysk dostawcy) znajdziesz w artykule Partycje rozruchowe.