Kompilowanie jąder

Na tej stronie szczegółowo opisujemy proces tworzenia niestandardowych jądrem urządzeń z Androidem. Te przeprowadzi Cię przez proces wyboru odpowiedniego źródeł, tworzenia jądra i umieszczania wyników w obrazie systemu stworzone na podstawie projektu Android Open Source Project (AOSP).

Możesz pobrać nowsze źródła jądra przy użyciu Repozytorium; aby je stworzyć, przez uruchomienie build/build.sh w katalogu głównym proces płatności źródłowy.

Pobieranie źródeł i narzędzi do kompilacji

W przypadku najnowszych jąder użyj repo , aby pobrać źródła, łańcuch narzędzi i skrypty. Niektóre jądra (na przykład jądra Pixela 3) wymagają źródeł z wielu git podczas gdy inne (na przykład typowe jądra) wymagają tylko jednego źródła. Użycie metody repo zapewnia prawidłowe źródło konfigurację katalogu.

Pobierz źródła dla odpowiedniej gałęzi:

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

Lista gałęzi repozytorium (BRANCH), których można używać z poprzednim `repo init`; patrz Ggałęzie jądra i ich systemy kompilacji.

Szczegółowe informacje o pobieraniu i kompilowaniu jąder urządzeń Pixel znajdziesz na stronie Tworzenie jąder pikseli.

Skompilowanie jądra

Tworzenie przy użyciu Bazel (Kleaf)

W Androidzie 13 wprowadzono jądra w systemie Bazel.

Aby utworzyć jądro GKI dla architektury aarch64, od gałęzi Androida Common Jądro nie może być wcześniejsza niż Android 13, następnie uruchom to polecenie:

tools/bazel build //common:kernel_aarch64_dist

Aby utworzyć dystrybucję, uruchom polecenie:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

Plik binarny jądra, moduły i odpowiadające im obrazy znajdują się w pliku Katalog $DIST_DIR. Jeśli wartość --dist_dir nie jest określona, sprawdź dane wyjściowe polecenia lokalizacji artefaktów. Aby dowiedzieć się więcej, zapoznaj się z dokumentacji AOSP.

Tworzenie z użyciem build.sh (starsza wersja)

w przypadku oddziałów Androida 12 lub starszych wersji LUB gałęzie bez Kleaf:

build/build.sh

Plik binarny jądra, moduły i odpowiadający mu obraz znajdują się w Katalog out/BRANCH/dist.

Tworzenie modułów dostawcy dla urządzenia wirtualnego

W Androidzie 13 wprowadzono jądra w systemie Bazel (Kleaf), zastępując build.sh.

Aby utworzyć moduły virtual_device, uruchom polecenie:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

Aby utworzyć dystrybucję, uruchom polecenie:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR

Więcej informacji o tworzeniu jąder Androida za pomocą usługi Bazel znajdziesz tutaj. Kleaf – tworzenie rdzeni Androida przy użyciu Bazel.

Szczegółowe informacje na temat obsługi Kleaf w przypadku poszczególnych architektur znajdziesz w artykule Obsługa Kleaf w przypadku urządzeń i jąder.

Tworzenie modułów dostawcy dla urządzenia wirtualnego za pomocą pliku build.sh (starsza wersja)

Na Androidzie 12 mątwy i złota rybka są takie same, że to samo jądro: virtual_device. Aby skompilować moduły jądra, użyj tej kompilacji Konfiguracja:

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh

Wprowadzenie Androida 11 GKI który dzieli jądra systemu na obsługiwany przez Google obraz jądra i moduły utrzymywane przez dostawcę, które tworzy się oddzielnie.

Ten przykład przedstawia konfigurację obrazu jądra:

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

Ten przykład przedstawia konfigurację modułu (mątwy i emulator):

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

Uruchamianie jądra

Niestandardowe jądro można uruchomić na kilka sposobów. Oto do różnych scenariuszy programowania.

Umieść w kompilacji obrazu Androida

Skopiuj plik Image.lz4-dtb do odpowiedniej lokalizacji binarnej jądra w drzewie AOSP i od nowa skompiluj obraz rozruchowy.

Możesz też zdefiniować TARGET_PREBUILT_KERNEL podczas korzystania z funkcji make bootimage (lub dowolnej innej make wiersza poleceń, który tworzy obraz rozruchowy). Ta zmienna to obsługiwane przez wszystkie urządzenia po skonfigurowaniu za pomocą device/common/populate-new-device.sh Na przykład:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

flash i uruchamianie jąder w trybie szybkiego rozruchu;

Większość współczesnych urządzeń ma rozszerzenie programu rozruchowego, które upraszcza proces podczas generowania i uruchamiania obrazu rozruchowego.

Aby uruchomić jądro bez aktualizacji:

adb reboot bootloader
fastboot boot Image.lz4-dtb

W przypadku tej metody jądro nie jest instalowane i nie będzie trwałe po ponownym uruchomieniu.

Uruchom jądro na mątwie

W wybranej architekturze możesz uruchamiać jądra w wybranej architekturze Urządzenia mątwy.

Aby uruchomić urządzenie Cuttlefish z określonym zestawem jądra systemu artefaktów, uruchom polecenie cvd start z docelowymi artefaktami jądra jako . Poniższe przykładowe polecenie używa artefaktów jądra dla środowiska docelowego arm64 z Plik manifestu jądra common-android14-6.1.

cvd start \
    -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: Utwórz jądra mątwy.

Dostosuj kompilację jądra

Aby dostosować kompilacje jądra pod kątem kompilacji Kleaf, zapoznaj się z artykułem Dokumentacja Kleaf.

Dostosowywanie kompilacji jądra przy użyciu pliku build.sh (starsza wersja)

W przypadku aplikacji build/build.sh proces kompilacji i jego wynik mogą mieć wpływ według zmiennych środowiskowych. Większość z nich jest opcjonalna, a każda gałąź jądra powinna mieć odpowiedni konfiguracji domyślnej. Tutaj znajdziesz listę najczęściej używanych. Dla pełną (i aktualną) listę, zapoznaj się z tym artykułem: build/build.sh.

Zmienna środowiskowa Opis Przykład
BUILD_CONFIG Plik konfiguracyjny kompilacji, z którego zainicjujesz środowisko kompilacji. Lokalizacja musi być zdefiniowana względem katalogu głównego repozytorium katalogu. Domyślna wartość to build.config.
Obowiązkowe w przypadku popularnych jąder.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Zastąp kompilator, który ma być używany. Przywraca wartość domyślną kompilator zdefiniowany przez build.config. CC=clang
DIST_DIR Podstawowy katalog wyjściowy dla 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 na potrzeby kompilacji lokalnych

W Androidzie 14 i nowszych możesz używać fragmentów defconfig aby dostosować konfiguracje jądra systemu operacyjnego. zobacz Dokumentacja Kleaf na temat fragmentów defconfig.

Niestandardowa konfiguracja jądra lokalnych kompilacji z konfiguracjami kompilacji (starsza wersja)

W Androidzie 13 i starszych wersjach zapoznaj się z poniższymi informacjami.

Jeśli musisz regularnie zmieniać opcję konfiguracji jądra, na przykład podczas pracy nad funkcją lub jeśli potrzebna jest opcja ustawienia możesz osiągnąć tę elastyczność, utrzymując lokalne modyfikacji lub kopii konfiguracji kompilacji.

Ustaw zmienną POST_DEFCONFIG_CMDS na instrukcję, która jest jest oceniana zaraz po zwykłej make defconfig kroku, która wynosi gotowe. Pliki build.config są pobierane do kompilacji funkcje zdefiniowane w funkcji build.config mogą być wywoływane w ramach poleceń post-defconfig.

Typowym przykładem jest wyłączenie optymalizacji czasu linku (LTO) dla kresek w postaci krzyżowej. jądra systemu podczas programowania. Z kolei LTO jest korzystne dla opublikowanych jąder, narzut może być istotny w momencie kompilacji. Następujący fragment został dodany do lokalnego interfejsu build.config wyłącza na stałe LTO, gdy za pomocą: 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)
}

Identyfikowanie wersji jądra

Prawidłową wersję do skompilowania możesz wskazać na podstawie 2 źródeł: drzewa AOSP oraz obraz systemu.

Wersja jądra z drzewa AOSP

Drzewo AOSP zawiera gotowe wersje jądra. Git log ujawnia prawidłową wersję w ramach komunikatu zatwierdzenia:

cd $AOSP/device/VENDOR/NAME
git log --max-count=1

Jeśli wersji jądra nie ma w dzienniku Git, pobierz ją z systemu jak opisano poniżej.

Wersja jądra z obrazu systemu

Aby określić wersję jądra systemu używaną w obrazie systemu, uruchom to bezpośrednio z plikiem jądra systemu operacyjnego:

file kernel

W przypadku plików typu Image.lz4-dtb uruchom polecenie:

grep -a 'Linux version' Image.lz4-dtb

Tworzenie obrazu rozruchowego

Obraz rozruchowy można utworzyć, korzystając ze środowiska kompilacji jądra.

Tworzenie obrazu rozruchowego dla urządzeń z parametrem init_boot

Urządzenia z partycji init_boot, obraz rozruchowy jest kompilowany razem z jądrem systemu. Obraz initramfs nie jest umieszczony w witrynie w obrazie rozruchowym.

Na przykład w przypadku Kleaf możesz skompilować obraz rozruchowy GKI za pomocą:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

W wersji build/build.sh (starszej) możesz utworzyć obraz rozruchowy GKI za pomocą:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

Obraz rozruchowy GKI znajduje się w regionie $DIST_DIR.

Tworzenie obrazu rozruchowego dla urządzeń bez parametru init_boot (starsza wersja)

Urządzenia bez partycji init_boot, potrzebny jest plik binarny Ramdisk, który można pobrać pobieranie obrazu rozruchowego GKI i rozpakowywania. Każdy obraz rozruchowy GKI z powiązanej wersji Androida będzie działać.

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 tworzysz aplikację w wersji głównej AOSP, możesz zamiast tego pobrać ramdisk-recovery.img artefakt kompilacji z kompilacji aosp_arm64 ci.android.com i użyj go jako pliku binarnego ramdisk.

Gdy masz plik binarny Ramdisk skopiowany do folderu gki-ramdisk.lz4 w katalogu głównym w katalogu kompilacji jądra systemu, możesz wygenerować obraz rozruchowy, wykonując 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 używasz architektury opartej na x86, zastąp Image z użytkownikami bzImage i aarch64 oraz 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ę pod adresem out/<kernel branch>/dist/boot.img.