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 montowanie partycji. Aby umożliwić urządzeniu montowanie partycji i kontynuację uruchamiania, pierwszy etap init został ulepszony w celu załadowania modułów jądra znajdujących się na ramdysku. Ramdysk jest podzielony na ramdyski ogólne i dostawcy. Moduły jądra dostawcy są przechowywane w ramdysku dostawcy. Kolejność ładowania modułów jądra jest konfigurowalna.

Lokalizacja modułu

Ramdysk jest systemem plików dla pierwszego etapu init, oraz dla obrazu odzyskiwania/fastbootd na urządzeniach A/B i wirtualnych A/B. Jest to plik initramfs składający się z dwóch archiwów cpio, które są łączone przez program ładujący. Pierwsze archiwum cpio, które jest przechowywane jako ramdysk dostawcy na partycji rozruchowej dostawcy, zawiera następujące komponenty:

  • Moduły jądra dostawcy pierwszego etapu init , zlokalizowane w /lib/modules/ .
  • pliki konfiguracyjne modprobe , znajdujące się w /lib/modules/ : modules.dep , modules.softdep , modules.alias , modules.options .
  • Plik modules.load wskazujący, które moduły mają zostać załadowane podczas pierwszego etapu inicjalizacji i w jakiej kolejności, w /lib/modules/ .
  • Moduły jądra odzyskiwania dostawcy dla urządzeń A/B i wirtualnych A/B, w /lib/modules/
  • modules.load.recovery , który wskazuje moduły do ​​załadowania i w jakiej kolejności, dla urządzeń A/B i wirtualnych A/B, w /lib/modules .

Drugie archiwum cpio, które jest dostarczane z GKI jako ramdysk pliku boot.img i nałożone na pierwsze, zawiera first_stage_init i biblioteki, od których to zależy.

Ładowanie modułu w pierwszym etapie init

init pierwszego etapu rozpoczyna się od odczytania plików konfiguracyjnych modprobe z /lib/modules/ na ramdysku. Następnie czyta listę modułów określoną w /lib/modules/modules.load (lub w przypadku odzyskiwania, /lib/modules/modules.load.recovery ) i próbuje załadować każdy z tych modułów w kolejności, zgodnie z instrukcją konfiguracja określona we wcześniej załadowanych plikach. Żądana kolejność może zostać odrzucona w celu spełnienia twardych lub miękkich zależności.

Zbuduj wsparcie, pierwszy etap init

Aby określić moduły jądra, które mają zostać skopiowane na ramdysk dostawcy cpio, wypisz je w BOARD_VENDOR_RAMDISK_KERNEL_MODULES . Kompilacja uruchamia depmod na tych modułach i umieszcza powstałe pliki konfiguracyjne modprobe na dysku RAM dostawcy cpio.

Kompilacja tworzy również plik modules.load i przechowuje go w cpio na dysku RAM dostawcy. Domyślnie zawiera wszystkie moduły wymienione w 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

Zbuduj wsparcie, pełny Android

Podobnie jak w przypadku Androida 10 i wcześniejszych wersji, moduły jądra wymienione w BOARD_VENDOR_KERNEL_MODULES są kopiowane przez wbudowaną platformę Android do partycji dostawcy w /vendor/lib/modules . Wersja platformy uruchamia depmod na tych modułach i kopiuje pliki wyjściowe depmod na partycję dostawcy w tej samej lokalizacji. Mechanizm ładowania modułów jądra z /vendor pozostaje taki sam, jak w poprzednich wersjach Androida. To Twoja decyzja, jak i kiedy załadować te moduły, chociaż zazwyczaj 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 Android, mogą napotkać problem przy użyciu wyżej wymienionych makr BOARD w celu określenia modułów jądra, które mają zostać skopiowane na urządzenie. Jeśli sprzedawca chce uniknąć umieszczania modułów jądra w plikach kompilacji platformy urządzenia, może użyć symbolu wieloznacznego ( $(wildcard device/vendor/mydevice/*.ko ). Należy pamiętać, że symbol wieloznaczny nie działa w przypadku zintegrowanego kompilacja jądra, ponieważ po wywołaniu make i makra są rozwijane w plikach makefile, moduły jądra nie zostały zbudowane, więc makra są puste.

Aby obejść ten problem, dostawca może zlecić kompilacji jądra utworzenie archiwum zip zawierającego moduły jądra, które mają zostać skopiowane na każdą partycję. Ustaw ścieżkę tego archiwum zip w BOARD_*_KERNEL_MODULES_ARCHIVE , gdzie * jest nazwą partycji (np. BOARD_VENDOR_KERNEL_MODULES_ARCHIVE ). Wersja na platformę Android rozpakowuje to archiwum zip do odpowiedniej lokalizacji i uruchamia depmod na modułach.

Archiwum zip modułu jądra powinno mieć regułę tworzenia, która gwarantuje, że kompilacja platformy będzie mogła wygenerować archiwum, jeśli zajdzie taka potrzeba.

Powrót do zdrowia

We wcześniejszych wersjach Androida moduły jądra wymagane do odzyskiwania były określone w BOARD_RECOVERY_KERNEL_MODULES . W systemie Android 11 moduły jądra wymagane do odzyskiwania są nadal określane za pomocą tego makra. Jednakże moduły jądra odzyskiwania są kopiowane do RAMdysku cpio dostawcy, a nie do ogólnego RAMdysku cpio. Domyślnie wszystkie moduły jądra wymienione w BOARD_RECOVERY_KERNEL_MODULES są ładowane podczas pierwszego etapu init . Jeśli chcesz, aby został załadowany tylko podzbiór tych modułów, określ zawartość tego podzbioru w BOARD_RECOVERY_KERNEL_MODULES_LOAD .

Aby dowiedzieć się więcej na temat tworzenia partycji rozruchowej dostawcy (która zawiera ramdysk dostawcy wspomniany na tej stronie), zobacz Partycje rozruchowe .