Построение ядер

На этой странице подробно описан процесс создания пользовательских ядер для устройств Android. Эти инструкции проведут вас через процесс выбора правильных исходных кодов, сборки ядра и внедрения результатов в образ системы, созданный на основе проекта Android с открытым исходным кодом (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 для ядер, доступных с помощью этого метода.

Устройство Бинарный путь в дереве AOSP Филиалы репо
Пиксель 6а (голубая сойка) устройство/google/bluejay-kernel android-gs-bluejay-5.10-android12L-d2
Пиксель 6 (иволга)
Pixel 6 Pro (ворон)
устройство/google/равиоль-ядро android-gs-равиоль-5.10-android12L
Пиксель 5а (барбет) устройство/google/барбет-ядро Android-msm-барбет-4.19-android12L
Пиксель 5 (красноперый)
Pixel 4a (5G) (ежевика)
устройство/google/redbull-kernel android-msm-redbull-4.19-android12L
Пиксель 4а (солнечная рыба) устройство/google/sunfish-kernel android-msm-sunfish-4.14-android12L
Пиксель 4 (пламя)
Pixel 4 XL (коралловый)
устройство/google/coral-kernel android-msm-coral-4.14-android12L
Пиксель 3а (сарго)
Pixel 3a XL (бонито)
устройство/google/bonito-ядро android-msm-bonito-4.9-android12L
Пиксель 3 (синяя линия)
Pixel 3 XL (штриховка)
устройство / google / crosshatch-kernel android-msm-штриховка-4.9-android12
Пиксель 2 (судак)
Pixel 2 XL (таймень)
устройство/google/wahoo-ядро android-msm-wahoo-4.4-android10-qpr3
Пиксель (парусник)
Pixel XL (марлин)
устройство/google/marlin-kernel Android-msm-marlin-3.18-pie-qpr2
Хайкей960 устройство/linaro/hikey-kernel хайки-линаро-андроид-4.14
хайки-линаро-андроид-4.19
общий-андроид12-5.4
Бигль x15 устройство/ti/beagle_x15-ядро омап-бигль-x15-андроид-4.14
омап-бигль-x15-андроид-4.19
Общее ядро ​​Android Н/Д общий-андроид-4.4
общий-андроид-4.9
общий-андроид-4.14
общий андроид-4.19
общий-андроид-4.19-стабильный
общий-андроид11-5.4
общий-андроид12-5.4
общий-андроид12-5.10
общий-андроид13-5.10
общий-андроид13-5.15
общий-Android-основной

Сборка ядра

Затем соберите ядро ​​следующим образом:

build/build.sh

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

Сборка модулей GKI

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

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

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

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

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

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

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.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

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

Настройка сборки ядра

На процесс сборки и результат могут влиять переменные среды. Большинство из них являются необязательными, и каждая ветка ядра должна иметь правильную конфигурацию по умолчанию. Здесь перечислены наиболее часто используемые из них. Полный (и актуальный) список см. в 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

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

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

Задайте для переменной 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

Создание загрузочного образа

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

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

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

Если вы разрабатываете с помощью AOSP master, вы можете вместо этого загрузить артефакт сборки 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 .