Na tej stronie szczegółowo opisano proces tworzenia niestandardowych jąder dla urządzeń z systemem Android. Te instrukcje poprowadzą Cię przez proces wybierania właściwych źródeł, budowania jądra i osadzania wyników w obrazie systemu zbudowanym na podstawie projektu Android Open Source Project (AOSP).
Możesz uzyskać nowsze źródła jądra, korzystając z Repo ; zbuduj je bez dalszej konfiguracji, uruchamiając build/build.sh
z katalogu głównego kasy źródłowej.
Pobierz źródła i narzędzia do tworzenia
W przypadku najnowszych jąder użyj repo
, aby pobrać źródła, zestaw narzędzi i skrypty kompilacji. Niektóre jądra (na przykład jądra Pixela 3) wymagają źródeł z wielu repozytoriów Git, podczas gdy inne (na przykład zwykłe jądra) wymagają tylko jednego źródła. Stosowanie podejścia repo
zapewnia poprawną konfigurację katalogu źródłowego.
Pobierz źródła dla odpowiedniego oddziału:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
Aby zapoznać się z listą gałęzi repo ( BRANCH ), których można użyć z poprzednim poleceniem `repo init`, zobacz Gałęzie jądra i ich systemy kompilacji .
Aby uzyskać szczegółowe informacje na temat pobierania i kompilowania jąder dla urządzeń Pixel, zobacz Tworzenie jąder Pixel .
Zbuduj jądro
Buduj z Bazelem (Kleaf)
W Androidzie 13 wprowadzono budowanie jąder za pomocą Bazela .
Aby zbudować jądro GKI dla architektury aarch64, sprawdź gałąź Android Common Kernel nie wcześniejszą niż Android 13, a następnie uruchom następującą komendę:
tools/bazel build //common:kernel_aarch64_dist
Aby utworzyć dystrybucję, uruchom:
tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR
Następnie plik binarny jądra, moduły i odpowiadające im obrazy znajdują się w katalogu $DIST_DIR
. Jeśli --dist_dir
nie jest określona, zobacz dane wyjściowe polecenia, aby poznać lokalizację artefaktów. Szczegółowe informacje można znaleźć w dokumentacji AOSP .
Kompiluj za pomocą build.sh (starsza wersja)
W przypadku oddziałów z Androidem 12 lub starszym LUB oddziałów bez Kleafa:
build/build.sh
Plik binarny jądra, moduły i odpowiadający im obraz znajdują się w katalogu out/ BRANCH /dist
.
Zbuduj moduły dostawcy dla urządzenia wirtualnego
W Androidzie 13 wprowadzono budowanie jąder za pomocą Bazela (Kleaf), zastępując build.sh
.
Aby zbudować moduły virtual_device
, uruchom:
tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist
Aby utworzyć dystrybucję, uruchom:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR
Więcej szczegółów na temat budowania jądra Androida za pomocą Bazela znajdziesz w artykule. Kleaf — Budowanie jądra Androida za pomocą Bazela .
Aby uzyskać szczegółowe informacje na temat obsługi Kleafa dla poszczególnych architektur, zobacz Wsparcie Kleafa dla urządzeń i jąder .
Zbuduj moduły dostawcy dla urządzenia wirtualnego za pomocą build.sh (starsze wersje)
W Androidzie 12 Mątwy i Złota Rybka są zbieżne, więc mają to samo jądro: virtual_device
. Aby zbudować 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 systemie Android 11 wprowadzono GKI , które dzieli jądro na obraz jądra utrzymywany przez Google i moduły obsługiwane przez dostawcę, które są budowane osobno.
Ten przykład pokazuje konfigurację obrazu jądra:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
Poniższy przykład pokazuje konfigurację modułu (mątwa i emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
Uruchom jądro
Istnieje wiele sposobów uruchomienia niestandardowego jądra. Poniżej przedstawiono znane sposoby odpowiednie dla różnych scenariuszy rozwoju.
Osadź w kompilacji obrazu Androida
Skopiuj Image.lz4-dtb
do odpowiedniej lokalizacji binarnej jądra w drzewie AOSP i odbuduj obraz rozruchowy.
Alternatywnie zdefiniuj zmienną TARGET_PREBUILT_KERNEL
podczas korzystania z make bootimage
(lub dowolnego innego wiersza poleceń make
, który tworzy obraz startowy). Ta zmienna jest obsługiwana przez wszystkie urządzenia, ponieważ jest skonfigurowana w device/common/populate-new-device.sh
. Na przykład:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
Flashuj i uruchamiaj jądra za pomocą fastboot
Najnowsze urządzenia mają rozszerzenie programu ładującego, które usprawnia proces generowania i uruchamiania obrazu rozruchowego.
Aby uruchomić jądro bez flashowania:
adb reboot bootloader
fastboot boot Image.lz4-dtb
Dzięki tej metodzie jądro w rzeczywistości nie jest flashowane i nie będzie się utrzymywać po ponownym uruchomieniu.
Uruchom jądra na mątwie
Możesz uruchamiać jądra w wybranej architekturze na urządzeniach mątwy .
Aby uruchomić urządzenie mątwy z określonym zestawem artefaktów jądra , uruchom komendę cvd start
z docelowymi artefaktami jądra jako parametrami. Poniższe przykładowe polecenie wykorzystuje artefakty jądra dla celu arm64 z 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
Aby uzyskać więcej informacji, zobacz Tworzenie jądra na mątwie .
Dostosuj kompilację jądra
Aby dostosować kompilacje jądra do kompilacji Kleafa, zobacz dokumentację Kleafa .
Dostosuj kompilację jądra za pomocą build.sh (starsza wersja)
W przypadku build/build.sh
na proces kompilacji i wynik mogą wpływać zmienne środowiskowe. Większość z nich jest opcjonalna i każda gałąź jądra powinna mieć odpowiednią domyślną konfigurację. Tutaj wymieniono najczęściej używane. Pełną (i aktualną) listę można znaleźć w build/build.sh
.
Zmienna środowiskowa | Opis | Przykład |
---|---|---|
BUILD_CONFIG | Kompiluj plik konfiguracyjny, z którego inicjujesz środowisko kompilacji. Lokalizacja musi być zdefiniowana względem katalogu głównego Repo. Domyślnie jest to build.config .Obowiązkowe dla popularnych jąder. | BUILD_CONFIG=common/build.config.gki.aarch64 |
CC | Zastąp kompilator, który ma być używany. Wraca do domyślnego kompilatora zdefiniowanego 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 dla 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 dla kompilacji lokalnych
W systemie Android 14 i nowszych możesz używać fragmentów defconfig do dostosowywania konfiguracji jądra. zobacz dokumentację Kleafa na temat fragmentów defconfig .
Niestandardowa konfiguracja jądra dla kompilacji lokalnych z konfiguracjami kompilacji (starsza wersja)
W systemie Android 13 i starszych zobacz poniższe informacje.
Jeśli musisz regularnie zmieniać opcję konfiguracji jądra, na przykład podczas pracy nad funkcją, lub jeśli potrzebujesz opcji do ustawienia w celach programistycznych, możesz osiągnąć tę elastyczność, zachowując lokalną modyfikację lub kopię konfiguracji kompilacji.
Ustaw zmienną POST_DEFCONFIG_CMDS na instrukcję, która jest oceniana zaraz po wykonaniu zwykłego kroku make defconfig
. Ponieważ pliki build.config
są pobierane ze środowiska kompilacji, funkcje zdefiniowane w build.config
można wywoływać w ramach poleceń post-defconfig.
Typowym przykładem jest wyłączenie optymalizacji czasu łącza (LTO) dla jąder crosshatch podczas programowania. Chociaż LTO jest korzystne dla wydanych jąder, obciążenie w czasie kompilacji może być znaczące. Poniższy fragment dodany do lokalnego build.config
trwale wyłącza LTO podczas korzystania z 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)
}
Zidentyfikuj wersje jądra
Właściwą wersję do zbudowania można zidentyfikować na podstawie dwóch źródeł: drzewa AOSP i obrazu systemu.
Wersja jądra z drzewa AOSP
Drzewo AOSP zawiera prekompilowane wersje jądra. Dziennik git ujawnia poprawną wersję jako część komunikatu zatwierdzenia:
cd $AOSP/device/VENDOR/NAME
git log --max-count=1
Jeśli wersja jądra nie jest wymieniona w dzienniku git, uzyskaj ją z obrazu systemu, jak opisano poniżej.
Wersja jądra z obrazu systemu
Aby określić wersję jądra używaną w obrazie systemu, uruchom następującą komendę w stosunku do pliku jądra:
file kernel
W przypadku plików Image.lz4-dtb
uruchom:
grep -a 'Linux version' Image.lz4-dtb
Utwórz obraz rozruchowy
Możliwe jest zbudowanie obrazu rozruchowego przy użyciu środowiska kompilacji jądra.
Zbuduj obraz rozruchowy dla urządzeń za pomocą init_boot
W przypadku urządzeń z partycją init_boot
obraz rozruchowy jest budowany wraz z jądrem. Obraz initramfs
nie jest osadzony w obrazie startowym.
Na przykład za pomocą Kleafa możesz zbudować obraz rozruchowy GKI za pomocą:
tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR
Za pomocą build/build.sh
(legacy) możesz zbudować obraz rozruchowy GKI za pomocą:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
Obraz rozruchowy GKI znajduje się w $DIST_DIR .
Zbuduj obraz rozruchowy dla urządzeń bez init_boot (starsza wersja)
W przypadku urządzeń bez partycji init_boot
potrzebny jest plik binarny ramdysku, który można uzyskać , pobierając obraz startowy GKI i rozpakowując go. 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 programujesz przy użyciu głównego AOSP, możesz zamiast tego pobrać artefakt kompilacji ramdisk-recovery.img
z kompilacji aosp_arm64 na ci.android.com i użyć go jako pliku binarnego ramdysku.
Kiedy masz plik binarny ramdysku i skopiowałeś go do gki-ramdisk.lz4
w katalogu głównym kompilacji jądra, możesz wygenerować obraz rozruchowy, wykonując:
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, zamień Image
na bzImage
i aarch64
na 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
Plik ten znajduje się w katalogu artefaktów $KERNEL_ROOT/out/$KERNEL_VERSION/dist
.
Obraz rozruchowy znajduje się w out/<kernel branch>/dist/boot.img
.