Obsługa modułu jądra

Ogólny obraz jądra (GKI) może nie zawierać wymaganej obsługi sterowników, aby umożliwić urządzeniu zamontowanie partycji. Aby umożliwić urządzeniu montowanie partycji i dalsze uruchamianie, pierwszy etap init został rozszerzony o możliwość wczytywania modułów jądra znajdujących się na dysku RAM. Dysk RAM jest podzielony na ogólny i dysk RAM dostawcy. Moduły jądra dostawcy są przechowywane w dysku RAM dostawcy. Kolejność ładowania modułów jądra można skonfigurować.

Lokalizacja modułu

Ramdysk to system plików na potrzeby pierwszego etapu init, oraz obrazu recovery/fastbootd na urządzeniach z A/B i wirtualnym A/B. Jest to initramfs składający się z 2 archiwów cpio, które są łączone przez program rozruchowy. Pierwsze archiwum cpio, które jest przechowywane jako ramdysk dostawcy w partycji vendor-boot, zawiera te komponenty:

  • Moduły jądra dostawcy na pierwszym etapie init znajdujące się w /lib/modules/.
  • modprobe pliki konfiguracyjne znajdujące się w /lib/modules/:modules.dep, modules.softdep,modules.alias, modules.options.
  • Plik modules.load, który wskazuje, które moduły mają być wczytywane podczas inicjowania pierwszego etapu i w jakiej kolejności w /lib/modules/.
  • Moduły jądra odzyskiwania dostawcy na urządzeniach A/B i wirtualnych A/B w folderze /lib/modules/
  • modules.load.recovery wskazujący moduły do wczytania i kolejność ich wczytywania na urządzeniach z testami A/B i wirtualnymi testami A/B, w /lib/modules.

Drugie archiwum cpio, które jest dostarczane z GKI jako dysk RAM obrazu rozruchowego i nakładane na pierwsze, zawiera first_stage_init i biblioteki, od których zależy.

Wczytywanie modułu w pierwszej fazie inicjowania

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 /lib/modules/modules.load (lub w przypadku przywracania – w /lib/modules/modules.load.recovery) i próbuje załadować każdy z tych modułów w kolejności, zgodnie z konfiguracją określoną w wcześniej załadowanych plikach. Żądana kolejność może zostać zmieniona, aby spełnić wymagania dotyczące zależności twardych lub miękkich.

Obsługa kompilacji, inicjowanie pierwszego etapu

Aby określić moduły jądra, które mają zostać skopiowane do pliku cpio ramdysku dostawcy, wymień je w BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Kompilacja jest przeprowadzanadepmod w tych modułach, a wynikowe pliki konfiguracji modprobe są umieszczane w obrazie cpio dysku RAM dostawcy.

Podczas kompilacji tworzony jest też plik modules.load, który jest przechowywany w plikach cpio ramdysku dostawcy. Domyślnie zawiera wszystkie moduły wymienione w sekcjiBOARD_VENDOR_RAMDISK_KERNEL_MODULES. Aby zastąpić zawartość tego pliku, użyj znaku 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łna wersja Androida

Podobnie jak w przypadku Androida 10 i starszych wersji, moduły jądra wymienione w  BOARD_VENDOR_KERNEL_MODULES są kopiowane przez platformę Android do partycji dostawcy w /vendor/lib/modules. Proces kompilacji platformy depmod jest uruchamiany w tych modułach i kopiuje pliki wyjściowe depmod do partycji dostawcy w tym samym miejscu. Mechanizm ładowania modułów jądra z /vendorpozostaje taki sam jak w poprzednich wersjach Androida. To Ty decydujesz, jak i kiedy wczytywać te moduły, chociaż zwykle odbywa się to za pomocą init.rcskryptów.

Symbole wieloznaczne i zintegrowane kompilacje jądra

Dostawcy, którzy łączą kompilację jądra urządzenia z kompilacją platformy Android, mogą mieć problem z używaniem wspomnianych wyżej makr BOARD do określania modułów jądra, które mają być kopiowane na urządzenie. Jeśli dostawca chce uniknąć umieszczania modułów jądra w plikach kompilacji platformy urządzenia, może użyć symbolu wieloznacznego ($(wildcard device/vendor/mydevice/*.ko). Pamiętaj, że symbol wieloznaczny nie działa w przypadku zintegrowanej kompilacji jądra, ponieważ po wywołaniu polecenia make i rozwinięciu makr w plikach makefile moduły jądra nie zostały jeszcze skompilowane, więc makra są puste.

Aby obejść ten problem, dostawca może utworzyć w ramach kompilacji jądra archiwum ZIP zawierające moduły jądra, które mają zostać skopiowane do każdej partycji. Ustaw ścieżkę do tego archiwum ZIP w BOARD_*_KERNEL_MODULES_ARCHIVE, gdzie * to nazwa partycji (np. BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). Platforma Android wyodrębnia to archiwum ZIP do odpowiedniej lokalizacji i uruchamia depmod w modułach.

Archiwum ZIP modułu jądra powinno zawierać regułę make, która zapewnia, że kompilacja platformy może w razie potrzeby wygenerować archiwum.

Odzyskiwanie

W poprzednich wersjach Androida moduły jądra wymagane do odzyskiwania były określone w pliku BOARD_RECOVERY_KERNEL_MODULES. W Androidzie 12 moduły jądra wymagane do przywracania są nadal określane za pomocą tego makra. Moduły jądra odzyskiwania są jednak kopiowane do pliku cpio ramdysku dostawcy, a nie do ogólnego pliku cpio ramdysku. Domyślnie wszystkie moduły jądra wymienione w BOARD_RECOVERY_KERNEL_MODULES są ładowane podczas pierwszego etapu init. Jeśli chcesz wczytać tylko podzbiór tych modułów, określ jego zawartość w BOARD_RECOVERY_KERNEL_MODULES_LOAD.

Więcej informacji o tworzeniu partycji rozruchowej dostawcy (zawierającej dysk RAM dostawcy wspomniany na tej stronie) znajdziesz w sekcji Partycje rozruchowe.