Ta strona zawiera szczegółowe informacje o procesie tworzenia niestandardowych jąder na urządzenia z Androidem. Te instrukcje przeprowadzą Cię przez proces wybierania odpowiednich źródeł, tworzenia jądra i osadzania wyników w obrazie systemu utworzonym na podstawie Projekt Android Open Source (AOSP).
Pobieranie źródeł i narzędzi do tworzenia
W przypadku najnowszych jąder użyj repo
aby pobrać źródła, łańcuch narzędzi i skrypty kompilacji.
Niektóre jądra (np. jądra Pixela 3) wymagają źródeł z wielu repozytoriów Git
, a inne (np. jądra wspólne) – tylko jednego
źródła. Użycie repo zapewnia prawidłową konfigurację katalogu źródłowego.
Pobierz źródła odpowiedniej gałęzi:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
Listę gałęzi repozytorium (BRANCH), których można używać z poprzednim poleceniem `repo init`, znajdziesz w artykule Gałęzie jądra i ich systemy kompilacji.
Szczegółowe informacje o pobieraniu i kompilowaniu jąder na urządzenia Pixel znajdziesz w artykule Tworzenie jąder Pixela.
Tworzenie jądra
Tworzenie za pomocą Bazel (Kleaf)
W Androidzie 13 wprowadziliśmy tworzenie jąder za pomocą Bazel.
Aby utworzyć dystrybucję jądra GKI dla architektury aarch64, pobierz gałąź wspólnego jądra Androida nie starszą niż Android 13 i następnie uruchom to polecenie:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
Plik binarny jądra, moduły i odpowiadające im obrazy znajdują się w katalogu $DIST_DIR. Jeśli nie podasz --destdir, lokalizację artefaktów znajdziesz w danych wyjściowych polecenia. Więcej informacji znajdziesz w
dokumentacji AOSP.
Tworzenie za pomocą build.sh (starsza wersja)
W przypadku gałęzi w Androidzie 12 lub starszym albo gałęzi bez Kleaf:
build/build.sh
Plik binarny jądra, moduły i odpowiadający im obraz znajdują się w
out/BRANCH/dist katalogu.
Tworzenie modułów dostawcy na urządzenie wirtualne
W Androidzie 13 wprowadziliśmy tworzenie jąder za pomocą
Bazel (Kleaf), zastępując build.sh.
Aby utworzyć dystrybucję modułów virtual_device, uruchom to polecenie:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]
Więcej informacji o tworzeniu jąder Androida za pomocą Bazel znajdziesz w artykule. Kleaf – tworzenie jąder Androida za pomocą Bazel.
Szczegółowe informacje o obsłudze Kleaf w przypadku poszczególnych architektur znajdziesz w artykule Obsługa Kleaf na urządzeniach i w jądrach.
Tworzenie modułów dostawcy na urządzenie wirtualne za pomocą build.sh (starsza wersja)
W Androidzie 12 Cuttlefish i Goldfish są zbieżne, więc używają tego samego jądra: virtual_device. Aby utworzyć moduły tego jądra, użyj tej konfiguracji kompilacji:
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
W Androidzie 11 wprowadziliśmy GKI, które dzieli jądro na obraz jądra utrzymywany przez Google i moduły utrzymywane przez dostawcę, które są tworzone oddzielnie.
Ten przykład pokazuje konfigurację obrazu jądra:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
Ten przykład pokazuje konfigurację modułu (Cuttlefish i emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
Uruchamianie jądra
Istnieje kilka sposobów uruchamiania jądra utworzonego na zamówienie. Poniżej znajdziesz znane sposoby odpowiednie do różnych scenariuszy programowania.
Osadzanie w kompilacji obrazu Androida
Skopiuj Image.lz4-dtb do odpowiedniej lokalizacji pliku binarnego jądra
w drzewie AOSP i ponownie utwórz obraz rozruchowy.
Możesz też zdefiniować zmienną TARGET_PREBUILT_KERNEL
podczas używania make bootimage (lub dowolnego innego
make wiersza poleceń, który tworzy obraz rozruchowy). Ta zmienna jest
obsługiwana przez wszystkie urządzenia, ponieważ jest konfigurowana za pomocą
device/common/populate-new-device.sh. Przykład:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
Flashowanie i uruchamianie jąder za pomocą fastboot
Większość najnowszych urządzeń ma rozszerzenie programu rozruchowego, które upraszcza proces generowania i uruchamiania obrazu rozruchowego.
Aby uruchomić jądro bez flashowania:
adb reboot bootloaderfastboot boot Image.lz4-dtb
W przypadku tej metody jądro nie jest flashowane i nie będzie działać po ponownym uruchomieniu.
Uruchamianie jąder w Cuttlefish
Jądra możesz uruchamiać w wybranej architekturze na urządzeniach Cuttlefish.
Aby uruchomić urządzenie Cuttlefish z określonym zestawem artefaktów
jądra, uruchom polecenie cvd create z artefaktami jądra docelowego jako
parametrami. Poniższy przykład polecenia używa artefaktów jądra dla celu arm64 z
common-android14-6.1 manifestu jądra.
cvd create \-kernel_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/Image \-initramfs_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/initramfs.img
Więcej informacji znajdziesz w artykule Tworzenie jąder w Cuttlefish.
Dostosowywanie kompilacji jądra
Aby dostosować kompilacje jądra w przypadku kompilacji Kleaf, przeczytaj dokumentację Kleaf.
Dostosowywanie kompilacji jądra za pomocą build.sh (starsza wersja)
W przypadku build/build.sh na proces kompilacji i jego wynik mogą wpływać
zmienne środowiskowe.
Większość z nich jest opcjonalna, a każda gałąź jądra powinna mieć odpowiednią
konfigurację domyślną. Najczęściej używane zmienne są wymienione tutaj. Pełną (i aktualną) listę znajdziesz w build/build.sh.
| Zmienna środowiskowa | Opis | Przykład |
|---|---|---|
BUILD_CONFIG |
Plik konfiguracji kompilacji, z którego inicjujesz środowisko kompilacji.
Lokalizacja musi być zdefiniowana względem katalogu głównego repozytorium. Domyślnie jest to build.config.Obowiązkowe w przypadku jąder wspólnych. |
BUILD_CONFIG=common/build.config.gki.aarch64 |
CC |
Zastąpienie kompilatora, który ma być używany. Wracanie do domyślnego
kompilatora zdefiniowanego przez build.config. |
CC=clang |
DIST_DIR |
Podstawowy katalog wyjściowy dystrybucji jądra. | DIST_DIR=/path/to/my/dist |
OUT_DIR |
Podstawowy katalog wyjściowy kompilacji jądra. | OUT_DIR=/path/to/my/out |
SKIP_DEFCONFIG |
Pomiń make defconfig |
SKIP_DEFCONFIG=1 |
SKIP_MRPROPER |
Pomiń make mrproper |
SKIP_MRPROPER=1 |
Niestandardowa konfiguracja jądra w przypadku kompilacji lokalnych
W Androidzie 14 i nowszych możesz używać fragmentów defconfig do dostosowywania konfiguracji jądra. Więcej informacji znajdziesz w dokumentacji Kleaf na temat fragmentów defconfig.
Niestandardowa konfiguracja jądra w przypadku kompilacji lokalnych z konfiguracjami kompilacji (starsza wersja)
W Androidzie 13 i starszych wersjach zobacz te informacje.
Jeśli musisz regularnie przełączać opcję konfiguracji jądra, np. podczas pracy nad funkcją, lub jeśli potrzebujesz opcji ustawionej na potrzeby programowania, możesz uzyskać taką elastyczność, utrzymując lokalną modyfikację lub kopię konfiguracji kompilacji.
Ustaw zmienną POST_DEFCONFIG_CMDS na instrukcję, która jest
wykonywana bezpośrednio po wykonaniu zwykłego kroku make defconfig jest
gotowe. Ponieważ pliki build.config są źródłem środowiska kompilacji, funkcje zdefiniowane w build.config można wywoływać
w ramach poleceń post-defconfig.
Typowym przykładem jest wyłączenie optymalizacji czasu łączenia (LTO) w przypadku jąder crosshatch
podczas programowania. LTO jest korzystne w przypadku opublikowanych jąder,
obciążenie w czasie kompilacji może być znaczne. Ten fragment kodu dodany
do lokalnego pliku build.config trwale wyłącza LTO podczas używania build/build.sh.
POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
-d LTO \
-d LTO_CLANG \
-d CFI \
-d CFI_PERMISSIVE \
-d CFI_CLANG
(cd ${OUT_DIR} && \
make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}
Określanie wersji jądra
Prawidłową wersję do utworzenia możesz określić na podstawie 2 źródeł: drzewa AOSP i obrazu systemu.
Wersja jądra z drzewa AOSP
Drzewo AOSP zawiera wstępnie skompilowane wersje jądra. Dziennik Git ujawnia prawidłową wersję w ramach wiadomości o zatwierdzeniu:
cd $AOSP/device/VENDOR/NAMEgit log --max-count=1
Jeśli wersji jądra nie ma w dzienniku Git, pobierz ją z obrazu systemu zgodnie z opisem poniżej.
Wersja jądra z obrazu systemu
Aby określić wersję jądra używaną w obrazie systemu, uruchom to polecenie w pliku jądra:
file kernel
W przypadku plików Image.lz4-dtb uruchom to polecenie:
grep -a 'Linux version' Image.lz4-dtb
Tworzenie obrazu rozruchowego
Obraz rozruchowy można utworzyć za pomocą środowiska kompilacji jądra.
Tworzenie obrazu rozruchowego na urządzenia z init_boot
W przypadku urządzeń z
partycją init_boot,
obraz rozruchowy jest tworzony razem z jądrem. Obraz initramfs nie jest osadzony w obrazie rozruchowym.
Na przykład za pomocą Kleaf możesz utworzyć obraz rozruchowy GKI za pomocą tego polecenia:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
Za pomocą build/build.sh (starsza wersja) możesz utworzyć obraz rozruchowy GKI za pomocą tego polecenia:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
Obraz rozruchowy GKI znajduje się w $DIST_DIR.
Tworzenie obrazu rozruchowego na urządzenia bez init_boot (starsza wersja)
W przypadku urządzeń bez
partycji init_boot,
potrzebujesz pliku binarnego ramdysku, który możesz uzyskać,
pobierając obraz rozruchowy GKI
i rozpakowując go. Będzie działać dowolny obraz rozruchowy GKI z powiązanej wersji Androida.
tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4
Folder docelowy to katalog najwyższego poziomu drzewa jądra (bieżący katalog roboczy).
Jeśli programujesz w najnowszej gałęzi AOSP, możesz zamiast tego pobrać
ramdisk-recovery.img artefakt kompilacji z kompilacji aosp_arm64 na
ci.android.com i użyć go jako pliku binarnego ramdysku.
Gdy masz plik binarny ramdysku i skopiujesz go do gki-ramdisk.lz4 w katalogu głównym
kompilacji jądra, możesz wygenerować obraz rozruchowy, wykonując to polecenie:
BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
Jeśli pracujesz z architekturą opartą na x86, zastąp Image
przez bzImage, a aarch64 przez
x86_64:
BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
Ten plik znajduje się w katalogu artefaktów
$KERNEL_ROOT/out/$KERNEL_VERSION/dist.
Obraz rozruchowy znajduje się w out/<kernel branch>/dist/boot.img.