Ядра сборки

На этой странице подробно описан процесс создания пользовательских ядер для устройств Android. Эти инструкции помогут вам выбрать правильные источники, собрать ядро ​​и встроить результаты в образ системы, созданный на основе проекта Android Open Source Project (AOSP).

Вы можете получить более свежие исходные коды ядра, используя Repo ; создайте их без дальнейшей настройки, запустив build/build.sh из корня извлечения исходного кода.

Загрузите исходные коды и инструменты сборки.

Для последних ядер используйте repo для загрузки исходных кодов, набора инструментов и сценариев сборки. Некоторым ядрам (например, ядрам Pixel 3) требуются источники из нескольких репозиториев git, тогда как другим (например, общим ядрам) требуется только один источник. Использование подхода repo обеспечивает правильную настройку исходного каталога.

Загрузите исходники для соответствующей ветки:

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

Список ветвей репо ( BRANCH ), которые можно использовать с предыдущей командой `repo init`, см. в разделе Ветви ядра и их системы сборки .

Подробную информацию о загрузке и компиляции ядер для устройств Pixel см. в разделе Создание ядер Pixel .

Сборка ядра

Сборка с помощью Bazel (Kleaf)

В Android 13 появилась возможность сборки ядер с помощью Bazel .

Чтобы собрать ядро ​​GKI для архитектуры aarch64, проверьте ветку Android Common Kernel не ранее Android 13, а затем выполните следующую команду:

tools/bazel build //common:kernel_aarch64_dist

Чтобы создать дистрибутив, запустите:

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

После этого двоичный файл ядра, модули и соответствующие изображения располагаются в каталоге $DIST_DIR . Если --dist_dir не указан, см. выходные данные команды для определения местоположения артефактов. Подробности смотрите в документации по AOSP .

Сборка с помощью build.sh (устаревшая версия)

Для филиалов с Android 12 или ниже ИЛИ филиалов без Kleaf:

build/build.sh

Бинарный файл ядра, модули и соответствующий образ расположены в каталоге out/ BRANCH /dist .

Создайте модули поставщика для виртуального устройства.

В Android 13 появилась сборка ядер с помощью Bazel (Kleaf), заменив build.sh .

Чтобы собрать модули virtual_device , запустите:

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

Чтобы создать дистрибутив, запустите:

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

Более подробную информацию о сборке ядер Android с помощью Bazel см. Kleaf — Сборка ядер Android с помощью Bazel .

Подробности о поддержке Kleaf для отдельных архитектур см. в разделе Поддержка Kleaf для устройств и ядер .

Создайте модули поставщика для виртуального устройства с помощью build.sh (устаревшая версия).

В Android 12 Cuttlefish и Goldfish сходятся, поэтому используют одно и то же ядро: virtual_device . Чтобы собрать модули этого ядра, используйте следующую конфигурацию сборки:

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

В Android 11 появился GKI , который разделяет ядро ​​на образ ядра, поддерживаемый Google, и модули, поддерживаемые поставщиком, которые собираются отдельно.

В этом примере показана конфигурация образа ядра:

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

В этом примере показана конфигурация модуля (Каракатица и эмулятор):

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

Запустить ядро

Существует несколько способов запуска специально созданного ядра. Ниже приведены известные способы, подходящие для различных сценариев развития.

Встроить в сборку образа Android

Скопируйте Image.lz4-dtb в соответствующее двоичное расположение ядра в дереве AOSP и пересоберите загрузочный образ.

Альтернативно, определите переменную TARGET_PREBUILT_KERNEL при использовании make bootimage (или любой другой командной строки make , которая создает загрузочный образ). Эта переменная поддерживается всеми устройствами, поскольку она настроена через device/common/populate-new-device.sh . Например:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Прошивка и загрузка ядер с помощью fastboot

Большинство последних устройств имеют расширение загрузчика, позволяющее упростить процесс создания и загрузки загрузочного образа.

Чтобы загрузить ядро ​​без перепрошивки:

adb reboot bootloader
fastboot boot Image.lz4-dtb

При использовании этого метода ядро ​​фактически не перепрошивается и не сохраняется после перезагрузки.

Запустите ядра на каракатицах

Вы можете запускать ядра в выбранной вами архитектуре на устройствах Cuttlefish .

Чтобы загрузить устройство Cuttlefish с определенным набором артефактов ядра , запустите команду cvd create с целевыми артефактами ядра в качестве параметров. В следующем примере команды используются артефакты ядра для цели Arm64 из манифеста ядра common-android14-6.1 .

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

Дополнительные сведения см. в разделе Разработка ядер на Cuttlefish .

Настройте сборку ядра

Чтобы настроить сборки ядра для сборок Kleaf, см. документацию Kleaf .

Настройте сборку ядра с помощью build.sh (устаревшая версия)

Для build/build.sh на процесс и результат сборки могут влиять переменные среды. Большинство из них являются необязательными, и каждая ветвь ядра должна иметь правильную конфигурацию по умолчанию. Здесь перечислены наиболее часто используемые из них. Полный (и актуальный) список см. в build/build.sh .

Переменная среды Описание Пример
BUILD_CONFIG Создайте файл конфигурации сборки, из которого вы инициализируете среду сборки. Местоположение должно быть определено относительно корневого каталога репо. По умолчанию — build.config .
Обязательно для общих ядер.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Переопределить используемый компилятор. Возвращается к компилятору по умолчанию, определенному в build.config . CC=clang
DIST_DIR Базовый выходной каталог для дистрибутива ядра. DIST_DIR=/path/to/my/dist
OUT_DIR Базовый выходной каталог для сборки ядра. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG Пропустить make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER Пропустить, make mrproper SKIP_MRPROPER=1

Пользовательская конфигурация ядра для локальных сборок

В Android 14 и более поздних версиях вы можете использовать фрагменты defconfig для настройки конфигурации ядра. см . документацию Kleaf по фрагментам defconfig .

Пользовательская конфигурация ядра для локальных сборок с конфигурациями сборки (устаревшие версии)

В Android 13 и более ранних версиях см. следующее.

Если вам необходимо регулярно переключать параметр конфигурации ядра, например, при работе над какой-либо функцией, или если вам нужно установить параметр для целей разработки, вы можете добиться такой гибкости, поддерживая локальную модификацию или копию конфигурации сборки.

Задайте для переменной POST_DEFCONFIG_CMDS оператор, который вычисляется сразу после выполнения обычного шага make defconfig . Поскольку файлы build.config передаются в среду сборки, функции, определенные в build.config можно вызывать как часть команд post-defconfig.

Типичным примером является отключение оптимизации времени компоновки (LTO) для ядер перекрестной штриховки во время разработки. Хотя LTO полезен для выпущенных ядер, накладные расходы во время сборки могут быть значительными. Следующий фрагмент, добавленный в локальный build.config постоянно отключает LTO при использовании 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)
}

Определить версии ядра

Вы можете определить правильную версию для сборки из двух источников: дерева AOSP и образа системы.

Версия ядра из дерева AOSP

Дерево AOSP содержит готовые версии ядра. Журнал git показывает правильную версию как часть сообщения о фиксации:

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

Если версия ядра не указана в журнале git, получите ее из образа системы, как описано ниже.

Версия ядра из образа системы

Чтобы определить версию ядра, используемую в образе системы, выполните следующую команду для файла ядра:

file kernel

Для файлов Image.lz4-dtb выполните:

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

Создайте загрузочный образ

Можно создать загрузочный образ, используя среду сборки ядра.

Создайте загрузочный образ для устройств с помощью init_boot.

Для устройств с разделом init_boot загрузочный образ собирается вместе с ядром. Образ initramfs не встроен в загрузочный образ.

Например, с помощью Kleaf вы можете создать загрузочный образ GKI с помощью:

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

С помощью build/build.sh (устаревшего) вы можете собрать загрузочный образ GKI с помощью:

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

Загрузочный образ GKI находится в $DIST_DIR .

Создайте загрузочный образ для устройств без init_boot (устаревший)

Для устройств без раздела init_boot необходим бинарный файл ramdisk, который можно получить, скачав загрузочный образ GKI и распаковав его. Подойдет любой загрузочный образ GKI из соответствующей версии Android.

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4

Целевая папка — это каталог верхнего уровня дерева ядра (текущий рабочий каталог).

Если вы разрабатываете с использованием AOSP main, вы можете вместо этого загрузить артефакт сборки ramdisk-recovery.img из сборки aosp_arm64 на ci.android.com и использовать его в качестве двоичного файла ramdisk.

Если у вас есть двоичный файл виртуального диска и вы скопировали его в gki-ramdisk.lz4 в корневом каталоге сборки ядра, вы можете создать загрузочный образ, выполнив:

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

Если вы работаете с архитектурой на базе x86, замените Image на bzImage и aarch64 на 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

Этот файл находится в каталоге артефакта $KERNEL_ROOT/out/$KERNEL_VERSION/dist .

Загрузочный образ находится по адресу out/<kernel branch>/dist/boot.img .