Ta strona szczegółowo opisuje proces tworzenia niestandardowych jąder dla urządzeń z systemem Android. Te instrukcje przeprowadzą Cię przez proces wybierania odpowiednich źródeł, budowania jądra i osadzania wyników w obrazie systemu zbudowanym z Android Open Source Project (AOSP).
Możesz uzyskać nowsze źródła jądra za pomocą Repo ; zbuduj je bez dalszej konfiguracji, uruchamiając build/build.sh
z katalogu głównego kasy źródłowej.
Pobieranie źródeł i narzędzi do budowania
W przypadku najnowszych jąder użyj repo
, aby pobrać źródła, łańcuch narzędzi i skrypty kompilacji. Niektóre jądra (na przykład jądra Pixel 3) wymagają źródeł z wielu repozytoriów git, podczas gdy inne (na przykład wspólne jądra) wymagają tylko jednego źródła. Korzystanie z podejścia repo
zapewnia poprawną konfigurację katalogu źródłowego.
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
W poniższej tabeli wymieniono nazwy BRANCH dla jąder dostępnych za pomocą tej metody.
Urządzenie | Ścieżka binarna w drzewie AOSP | Oddziały repo |
---|---|---|
Pixel 7 (pantera) Pixel 7 Pro (gepard) | urządzenie/google/pantah-kernel | android-gs-pantah-5.10-android13-qpr2 |
Pixel 6a (bluejay) | urządzenie/google/bluejay-kernel | android-gs-bluejay-5.10-android13-qpr2 |
Pixel 6 (wilga) Pixel 6 Pro (kruk) | device/google/raviole-kernel | android-gs-raviole-5.10-android13-qpr2 |
Pixel 5a (barbet) Piksel 5 (czerwonopłetwy) Pixel 4a (5G) (jeżyna) | urządzenie/google/redbull-kernel | android-msm-redbull-4.19-android13-qpr2 |
Pixel 4a (samosamochód) | device/google/sunfish-kernel | android-msm-sunfish-4.14-android13-qpr2 |
Piksel 4 (płomień) Pixel 4 XL (koralowy) | device/google/coral-kernel | android-msm-coral-4.14-android13 |
Pixel 3a (sargo) Pixel 3a XL (bonito) | urządzenie/google/bonito-kernel | android-msm-bonito-4.9-android12L |
Piksel 3 (niebieska linia) Pixel 3 XL (kreskowanie) | device/google/crosshatch-kernel | android-msm-crosshatch-4.9-android12 |
Piksel 2 (walleye) Pixel 2 XL (taimen) | urządzenie/google/jądro-wahoo | android-msm-wahoo-4.4-android10-qpr3 |
Piksel (żaglica) Pixel XL (marlin) | urządzenie/google/marlin-kernel | android-msm-marlin-3.18-pie-qpr2 |
Hikey960 | urządzenie/linaro/jądro-hikey | hikey-linaro-android-4.14 hikey-linaro-android-4.19 wspólny android 12-5.4 wspólny android 13-5.10 |
Pies gończy x15 | urządzenie/ti/beagle_x15-kernel | omap-beagle-x15-android-4.14 omap-beagle-x15-android-4.19 |
Wspólne jądro Androida | Nie dotyczy | wspólny Android-4.4 wspólny Android-4.9 wspólny Android-4.14 wspólny Android-4.19 wspólny-Android-4.19-stabilny wspólny android 11-5.4 wspólny android 12-5.4 wspólny android 12-5.10 wspólny android 13-5.10 wspólny android 13-5.15 wspólny android 14-5.15 wspólny Android 14-6.1 wspólna główna linia Androida |
Budowanie jądra
Następnie zbuduj jądro za pomocą tego:
build/build.sh
Plik binarny jądra, moduły i odpowiedni obraz znajdują się w katalogu out/ BRANCH /dist
.
Budynek z Bazelem (Kleaf)
Android 13 wprowadził jądra do budowania z Bazel , zastępując build/build.sh
.
Aby zbudować jądro GKI dla architektury aarch64, sprawdź gałąź Android Common Kernel nie wcześniej niż Android 13, a następnie uruchom następujące polecenie:
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 są umieszczane w katalogu $DIST_DIR
. Jeśli --dist_dir
nie zostanie określony, zobacz dane wyjściowe polecenia dotyczące lokalizacji artefaktów. Aby uzyskać szczegółowe informacje, zapoznaj się z dokumentacją AOSP .
Tworzenie modułów dostawcy dla urządzenia wirtualnego
Android 11 wprowadził GKI , który dzieli jądro na obraz jądra obsługiwany przez Google i moduły obsługiwane przez dostawcę, które są budowane 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 (mątwa i emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
W systemie Android 12 mątwa 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
Android 13 wprowadził jądra do budowania z Bazel (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
Aby uzyskać więcej informacji na temat budowania jądra Androida za pomocą Bazel, zobacz. Kleaf — budowanie jąder Androida za pomocą Bazel .
Aby uzyskać szczegółowe informacje na temat obsługi Kleaf dla poszczególnych architektur, zobacz Obsługa Kleaf dla urządzeń i jąder .
Obsługa Kleaf dla urządzeń i jąder
Poniższa tabela zawiera listę obsługi Kleaf dla poszczególnych jąder urządzeń. W przypadku niewymienionych urządzeń skontaktuj się z producentem urządzenia.
Urządzenie | Oddziały repo | Wsparcie Kleafa | wsparcie build/build.sh |
---|---|---|---|
Wspólne jądro Androida db845c Urządzenie wirtualne (x86_64, arm64) Urządzenie wirtualne (i686, ramię) Rockpi4 | wspólny Android-4.4 wspólny Android-4.9 wspólny Android-4.14 wspólny Android-4.19 wspólny-Android-4.19-stabilny wspólny android 11-5.4 wspólny android 12-5.4 wspólny android 12-5.10 | ❌ | ✅ |
Wspólne jądro Androida | wspólny android 13-5.10 wspólny android 13-5.15 | ✅ | ✅ (oficjalne) 1 |
Wspólne jądro Androida | wspólny android 14-5.15 wspólny Android 14-6.1 wspólna główna linia Androida | ✅ | ❌ |
db845c | wspólny android 13-5.10 | ❌ | ✅ |
db845c | wspólny android 13-5.15 | ✅ | ✅ (oficjalne) 1 |
db845c | wspólny android 14-5.15 wspólny Android 14-6.1 wspólna główna linia Androida | ✅ | ❌ |
Urządzenie wirtualne (x86_64, arm64) | wspólny android 13-5.10 wspólny android 13-5.15 | ✅ (oficjalne) 1 | ⚠️ (nieobsługiwany) 2 |
Urządzenie wirtualne (x86_64, arm64) | wspólny android 14-5.15 wspólny Android 14-6.1 wspólna główna linia Androida | ✅ | ❌ |
Urządzenie wirtualne (i686, ramię) | wspólny android 13-5.10 wspólny android 13-5.15 | ❌ | ✅ |
Urządzenie wirtualne (i686, ramię) | wspólny android 14-5.15 wspólny Android 14-6.1 wspólna główna linia Androida | ✅ | ❌ |
Rockpi4 | wspólny android 13-5.10 wspólny android 13-5.15 | ❌ | ✅ |
Rockpi4 | wspólny android 14-5.15 wspólny Android 14-6.1 wspólna główna linia Androida | ✅ | ❌ |
Hikey960 | hikey-linaro-android-4.14 hikey-linaro-android-4.19 wspólny android 12-5.4 wspólny android 13-5.10 | ❌ | ✅ |
moduł fips140 | wspólny android 12-5.10 wspólny android 13-5.10 wspólny android 13-5.15 | ❌ | ✅ |
moduł fips140 | wspólny android 14-5.15 | ✅ | ❌ |
1 „Oficjalny” oznacza, że jest to oficjalny sposób budowania jądra, chociaż alternatywny sposób może być również użyty do zbudowania jądra. 2 „Nieobsługiwany” oznacza, że budowanie jądra za pomocą tej metody powinno działać, ale metoda kompilacji nie jest stale testowana. W przyszłości może przestać się budować. Zamiast tego użyj „oficjalnego” sposobu budowania. |
Uruchamianie jądra
Istnieje wiele sposobów uruchamiania niestandardowego jądra. Poniżej przedstawiono znane sposoby odpowiednie dla różnych scenariuszy programistycznych.
Osadzanie w kompilacji obrazu systemu Android
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 polecenia make
, który tworzy boot image). Ta zmienna jest obsługiwana przez wszystkie urządzenia, ponieważ jest konfigurowana za pomocą device/common/populate-new-device.sh
. Na przykład:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
Flashowanie i ładowanie jądra za pomocą fastboot
Większość najnowszych urządzeń ma rozszerzenie programu ładującego, aby usprawnić proces generowania i uruchamiania obrazu rozruchowego.
Aby uruchomić jądro bez flashowania:
adb reboot bootloader
fastboot boot Image.lz4-dtb
Korzystając z tej metody, jądro nie jest w rzeczywistości flashowane i nie będzie się utrzymywać po ponownym uruchomieniu.
Dostosowanie kompilacji jądra
Aby dostosować kompilacje jądra do kompilacji Kleaf, zobacz dokumentację Kleaf .
W przypadku build/build.sh
na proces i wynik kompilacji mogą mieć wpływ zmienne środowiskowe. Większość z nich jest opcjonalna, a każda gałąź jądra powinna mieć odpowiednią domyślną konfigurację. Najczęściej używane są wymienione tutaj. Pełna (i aktualna) lista znajduje się na stronie build/build.sh
.
Zmienna środowiskowa | Opis | Przykład |
---|---|---|
BUILD_CONFIG | Zbuduj plik konfiguracyjny, z którego inicjujesz środowisko kompilacji. Lokalizacja musi być zdefiniowana względem katalogu głównego repozytorium. Domyślnie build.config .Obowiązkowe dla wspólnych jąder. | BUILD_CONFIG=common/build.config.gki.aarch64 |
CC | Zastąp kompilator, który ma być używany. Powraca 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
Jeśli musisz regularnie zmieniać opcję konfiguracji jądra, na przykład podczas pracy nad funkcją, lub jeśli potrzebujesz ustawić opcję do celów programistycznych, możesz osiągnąć tę elastyczność, utrzymują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 do środowiska kompilacji, funkcje zdefiniowane w build.config
mogą być wywoływane jako część poleceń post-defconfig.
Typowym przykładem jest wyłączenie optymalizacji czasu łącza (LTO) dla jąder krzyżowych podczas programowania. Chociaż LTO jest korzystne dla wydanych jąder, narzut w czasie kompilacji może być znaczny. Poniższy fragment kodu dodany do lokalnego 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)
}
Identyfikacja wersji jądra
Właściwą wersję do zbudowania można zidentyfikować z dwóch źródeł: drzewa AOSP i obrazu systemu.
Wersja jądra z drzewa AOSP
Drzewo AOSP zawiera gotowe 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ę względem pliku jądra:
file kernel
W przypadku plików Image.lz4-dtb
uruchom:
grep -a 'Linux version' Image.lz4-dtb
Tworzenie obrazu rozruchowego
Możliwe jest zbudowanie obrazu rozruchowego przy użyciu środowiska kompilacji jądra.
Tworzenie obrazu rozruchowego dla urządzeń za pomocą init_boot
W przypadku urządzeń z partycją init_boot
obraz rozruchowy jest tworzony wraz z jądrem. Obraz initramfs
nie jest osadzony w obrazie rozruchowym.
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
możesz zbudować obraz rozruchowy GKI za pomocą:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
Obraz startowy GKI znajduje się w $DIST_DIR .
Budowanie obrazu rozruchowego dla urządzeń bez init_boot
W przypadku urządzeń bez partycji init_boot
potrzebny jest plik binarny ramdysku, który można uzyskać, pobierając obraz rozruchowy 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 pracujesz z AOSP master, 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.
Gdy 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 architekturze 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
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
.