Obsługa modułu jądra

Ogólny obraz jądra (GKI) może nie zawierać wymaganego sterownika, aby umożliwić urządzeniu montowanie partycji. Aby umożliwić urządzeniu podłączanie partycji i kontynuowanie uruchamiania, ulepszony interfejs init pierwszego etapu umożliwia wczytywanie modułów jądra znajdujących się w ramdyzie. Ramdysk dzieli się na dyski ogólne i ramdyski dostawców. Moduły jądra dostawcy są przechowywane w dysku 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 jądra dostawcy init, 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ły dostawcy dotyczące odzyskiwania w jądrze – w przypadku urządzeń A/B i wirtualnych urządzeń A/B,/lib/modules/
  • modules.load.recovery, który wskazuje moduły do załadowania oraz ich kolejność w przypadku urządzeń A/B i wirtualnych urządzeń 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 odczytu plików konfiguracji modprobe z pliku /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 wykonywanadepmod na tych modułach, a wygenerowane pliki konfiguracyjne modprobe są umieszczane w pliku cpio w pamięci RAM 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 wersji Androida 10 i starszych, moduły jądra wymienione w BOARD_VENDOR_KERNEL_MODULES są kopiowane przez kompilację platformy Android na partycję dostawcy w miejscu /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. Decyzja o tym, jak i kiedy wczytać te moduły, należy do Ciebie. Zwykle odbywa się to przy użyciu 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ę tego archiwum ZIP w BOARD_*_KERNEL_MODULES_ARCHIVE, gdzie * to nazwa partycji (np. BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). Kompilacja platformy Androida wyodrębnia archiwum ZIP do odpowiedniej lokalizacji i uruchamia w modułach depmod.

Archiwum ZIP modułu jądra powinno mieć regułę tworzenia, która umożliwia kompilacji platformy wygenerowanie archiwum, gdy jest to wymagane.

Odzyskiwanie

W poprzednich wersjach Androida moduły jądra wymagane do przywracania został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 wczytywać tylko podzbiór tych modułów, określ zawartość tego podzbioru w polu BOARD_RECOVERY_KERNEL_MODULES_LOAD.

Informacje o tworzeniu partycji rozruchowej dostawcy (która zawiera wspomniany na tej stronie ramdysk dostawcy) znajdziesz w artykule Partycje rozruchowe.