Como criar kernels

Esta página detalha o processo de criação de kernels personalizados para dispositivos Android. As instruções a seguir oferecem orientação sobre o processo para selecionar as origens certas, criar o kernel e incorporar os resultados em uma imagem do sistema criada a partir do Android Open Source Project (AOSP).

Origens mais recentes de kernel podem ser adquiridas utilizando o repo e ser criadas sem outras configurações, executando build/build.sh a partir da raiz da saída da sua origem.

A raiz da saída da origem do kernel contém build/build.sh. A árvore do Android contém apenas binários pré-construídos do kernel. As árvores do kernel contêm as origens e todas as ferramentas para criar os kernels, incluindo este script.

Para ver informações sobre kernels mais antigos ou kernels não listados abaixo, consulte as instruções sobre como criar kernels legados.

Como fazer o download de origens e ferramentas de criação

Para kernels recentes, é possível fazer o download de origens, conjuntos de ferramentas e scripts de criação usando o repo. Alguns kernels (por exemplo, os do Pixel 3) exigem origens de vários repositórios git, enquanto outros, como os kernels comuns, exigem apenas uma. O uso da abordagem repo garante uma configuração correta do diretório de origem.

Faça o download das origens para o branch apropriado:

repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
A tabela a seguir lista os nomes de BRANCH para kernels disponíveis por meio desse método:
Dispositivo Caminho do binário na árvore AOSP Branches do repo
Pixel 3a (sargo) device/google/bonito-kernel android-msm-bonito-4.9-pie-b4s4
Pixel 3a XL (bonito)
Pixel 3 (blueline) device/google/crosshatch-kernel android-msm-crosshatch-4.9-pie-qpr2
Pixel 3 XL (crosshatch)
Pixel 2 (walleye) device/google/wahoo-kernel android-msm-wahoo-4.4-pie-qpr2
Pixel 2 XL (taimen)
Pixel (sailfish) device/google/marlin-kernel android-msm-marlin-3.18-pie-qpr2
Pixel XL (marlin)
Hikey device/linaro/hikey-kernel android-hikey-linaro-4.4
android-hikey-linaro-4.9
android-hikey-linaro-4.14
android-hikey-linaro-4.19
Hikey960 device/linaro/hikey-kernel android-hikey960-linaro-4.4
android-hikey960-linaro-4.9
android-hikey960-linaro-4.14
android-hikey960-linaro-4.19
Kernel comum do Android N/A common-android-4.4
common-android-4.9
common-android-4.14
common-android-4.19
common-android-mainline

Como criar o kernel

Em seguida, crie o kernel com:

build/build.sh

Observação: os kernels comuns são genéricos e personalizáveis e, portanto, não definem uma configuração padrão. Consulte a seção de criação personalizada para saber como especificar o BUILD_CONFIG para kernels comuns.

O binário, os módulos e a imagem correspondente do kernel estão localizados no diretório out/BRANCH/dist.

Como executar o kernel

Existem várias maneiras de executar um kernel personalizado. A seguir apresentamos as maneiras conhecidas que são adequadas para vários cenários de desenvolvimento:

Como incorporar na criação da imagem do Android

Copie a Image.lz4-dtb para o respectivo local do binário do kernel dentro da árvore AOSP e recrie a imagem de inicialização.

Outra alternativa é incluir a variável TARGET_PREBUILT_KERNEL ao usar make bootimage (ou qualquer outra linha de comando make que crie uma imagem de inicialização). Essa variável é compatível com todos os dispositivos, porque ela é configurada por device/common/populate-new-device.sh. Exemplo:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Como realizar uma atualização flash e inicializar kernels com fastboot

Os dispositivos mais recentes têm uma extensão do carregador de inicialização para otimizar o processo de geração e inicialização de uma bootimage. Para inicializar o kernel sem realizar uma atualização flash:

adb reboot bootloader
fastboot boot Image.lz4-dtb
Com o uso desse método, uma atualização flash não é realizada no kernel e, portanto, não persistirá durante a reinicialização.

Observação: os nomes do kernel diferem de acordo com o dispositivo. Para localizar o nome de arquivo correto do seu kernel, consulte device/VENDOR/NAME-kernel na árvore AOSP.

Personalizar a criação do kernel

O processo de criação e o resultado podem ser influenciados por variáveis de ambiente. A maior parte das variáveis é opcional e cada branch do kernel apresenta uma configuração padrão adequada. As mais usadas estão listadas aqui. Para ver uma lista completa (e atualizada), consulte build/build.sh.

Variável de ambiente Descrição Exemplo
BUILD_CONFIG Cria o arquivo de configuração para inicializar o ambiente de criação a partir dele. O local precisa ser definido em relação ao diretório raiz do repo. O padrão é "build.config".
Obrigatório para kernels comuns.
BUILD_CONFIG=common/build.config.cuttlefish.x86_64
OUT_DIR Diretório de saída base para a criação do kernel. OUT_DIR=/path/to/my/out
DIST_DIR Diretório de saída base para a distribuição do kernel. OUT_DIR=/path/to/my/dist
CC Substitui o compilador a ser usado. Volta para o compilador padrão definido pelo build.config. CC=clang
SKIP_MRPROPER Pula make mrproper SKIP_MRPROPER=1
SKIP_DEFCONFIG Pula make defconfig SKIP_DEFCONFIG=1

Configuração personalizada do kernel para criações locais

Se você precisar alternar regularmente uma opção de configuração do kernel, por exemplo, quando estiver trabalhando em um recurso ou se precisar configurar uma opção para fins de desenvolvimento, é possível conseguir essa flexibilidade mantendo uma modificação ou cópia local da configuração de criação.

Defina a variável POST_DEFCONFIG_CMDS como uma declaração que é avaliada logo após a etapa normal de make defconfig ter sido realizada. Como os arquivos build.config são originados no ambiente de criação, as funções definidas em build.config podem ser chamadas como parte dos comandos post-defconfig.

Um exemplo comum é desativar a Otimização de tempo de vinculação (LTO, na sigla em inglês) para kernels crosshatch durante o desenvolvimento. Embora a LTO seja benéfica para os kernels lançados, a sobrecarga no tempo de criação pode ser significativa. O snippet a seguir, incluído no build.config local, sempre desativará a LTO ao usar 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 CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}

Como identificar as versões do kernel

Há várias maneiras de identificar a versão correta a ser criada.

Versão do kernel da árvore AOSP

A árvore AOSP contém versões pré-criadas do kernel. Na maioria dos casos, o log do git revela a versão correta como parte da mensagem de confirmação:

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

Versão do kernel da imagem do sistema

Para determinar a versão do kernel usada em uma imagem do sistema, execute o seguinte comando no arquivo do kernel:

file kernel

Para arquivos Image.lz4-dtb, execute:

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