Ядра сборки

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

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

Для последних ядер используйте 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 run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

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

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

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

build/build.sh

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

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

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

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

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$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

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

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 .

Чтобы загрузить устройство 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 Файл конфигурации сборки, из которого вы инициализируете среду сборки. Расположение должно быть определено относительно корневого каталога Repo. По умолчанию 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) для ядер crosshatch во время разработки. Хотя 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 [-- --destdir=$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, вы можете вместо этого загрузить артефакт сборки ramdisk-recovery.img из сборки aosp_arm64 на ci.android.com и использовать его в качестве двоичного файла ramdisk.

Если у вас есть двоичный файл 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 .