Como atualizar seu kernel Android para o mais recente estável do Linux

Nós cobrimos guias sobre kernels Android, como “Como construir um kernel customizado” e “Melhores Kernels customizados para Android”, mas hoje vamos mostrar como fazer o upstream do seu kernel com o Linux estável mais recente.

Por favor, saibam que isto é avançado - se você nunca compilou um kernel antes, você deve seguir o guia “Como construir um kernel customizado” linkado acima, e este guia envolverá commits e combinações de commits do mais recente Linux- Kernel estável com o seu kernel Android antes de compilá-lo.

Fazer o upstream do kernel do seu Android para o Linux estável mais recente tem muitos benefícios positivos, como estar atualizado com os últimos commits de segurança e correções de bugs - explicaremos alguns dos prós e contras mais adiante neste guia.

O que é o kernel Linux-estável?

O Linux-stable, como o nome indica, é o braço estável do kernel do Linux. O outro braço é conhecido como "mainline", que é o branch master . Todo o desenvolvimento do kernel Linux acontece na linha principal e geralmente segue esse processo:

  1. Linus Torvalds levará um monte de patches de seus mantenedores por duas semanas.
  2. Após essas duas semanas, ele libera um kernel rc1 (por exemplo, 4.14-rc1).
  3. Para cada semana durante as próximas 6-8 semanas, ele lançará outro kernel RC (por exemplo, 4.14-rc2, 4.14-rc3, etc), que contém APENAS correções de erros e regressões.
  4. Uma vez que seja considerado estável, será lançado como um tarball para download em org (por exemplo, 4.14).

Quais são os kernels LTS?

Todo ano, Greg escolhe um kernel e o mantém por dois anos (LTS) ou seis anos (LTS estendido). Estes são projetados para ter produtos que precisam de estabilidade (como telefones Android ou outros dispositivos IOT). O processo é exatamente o mesmo que acima, isso só acontece por um longo tempo. Atualmente existem seis kernels LTS (que sempre podem ser vistos na página de lançamentos do kernel.org):

  • 4.14 (LTS), mantido por Greg Kroah-Hartman
  • 4.9 (LTS), mantido por Greg Kroah-Hartman
  • 4.4 (eLTS), mantido por Greg Kroah-Hartman
  • 4.1 (LTS), mantido por Sasha Levin
  • 3.16 (LTS), mantido por Ben Hutchings
  • 3.2 (LTS), mantido por Ben Hutchings

Quais são os benefícios do upstreaming do meu kernel do Android para o Linux Stable?

Quando vulnerabilidades importantes são divulgadas / corrigidas, os kernels estáveis ​​são os primeiros a obtê-los. Assim, o seu kernel Android será muito mais seguro contra ataques, falhas de segurança e apenas bugs em geral.

O Linux estável inclui correções para muitos drivers que meu dispositivo Android não usa, isso não é desnecessário?

Sim e não, dependendo de como você define “principalmente”. O kernel do Linux pode incluir um monte de código que não é utilizado no sistema Android, mas isso não garante que não haverá conflitos desses arquivos ao mesclar novas versões! Entenda que praticamente ninguém constrói cada parte do kernel, nem mesmo as distribuições Linux mais comuns, como Ubuntu ou Mint. Isso não significa que você não deveria estar tomando essas correções porque existem correções para os drivers que você executa. Considere arm / arm64 e ext4, por exemplo, que são a arquitetura e o sistema de arquivos Android mais comuns, respectivamente. Em 4.4, de 4.4.78 (versão da última tag Oreo CAF) para 4.4.121 (tag upstream mais recente), estes são os seguintes números para os commits desses sistemas:

 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 | wc-l2285 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 arch / arm | wc-l58 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 arch / arm64 | wc-l22 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 fs / ext4 | wc-l18 

A parte mais demorada é a inicial; uma vez que você esteja atualizado, não é preciso tempo para mesclar em uma nova versão, que geralmente não contém mais de 100 commits. Os benefícios que isso traz (mais estabilidade e melhor segurança para seus usuários) devem exigir esse processo.

Como mesclar o kernel estável do Linux em um kernel Android

Primeiro você precisa descobrir qual versão do kernel seu dispositivo Android está executando.

Por mais trivial que isso pareça, é necessário saber onde você precisa começar. Execute o seguinte comando na sua árvore de kernel:

 fazer a versão do kernel 

Ele retornará a versão em que você está. Os dois primeiros números serão usados ​​para descobrir o ramo que você precisa (por exemplo, linux-4.4.y para qualquer kernel 4.4) e o último número será usado para determinar qual versão você precisa começar com a fusão (por exemplo, se você estiver no 4.4 .21, você irá mesclar 4.4.22 próximo).

Pegue a última fonte do kernel em kernel.org

O kernel.org hospeda a fonte mais recente do kernel no repositório estável pelo linux. Na parte inferior dessa página, haverá três links de busca. Na minha experiência, o espelho do Google tende a ser o mais rápido, mas seus resultados podem variar. Execute os seguintes comandos:

 git remote add linux-stable //kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit buscar o linux-stable 

Decida se você deseja mesclar o kernel inteiro ou selecionar os commits

Em seguida, você precisará escolher se deseja mesclar os commits ou cherry-pick. Aqui estão os prós e contras de cada um e quando você pode querer fazê-los.

NOTA: Se a fonte do seu kernel estiver na forma de tarball, você provavelmente precisará escolher, caso contrário você receberá milhares de conflitos de arquivo porque o git está preenchendo o histórico baseado no upstream, não o que o OEM ou o CAF tem. mudou. Apenas pule para o passo 4.

Apanhar cerejas:

Prós:

  • Mais fácil de resolver conflitos, pois você sabe exatamente qual conflito está causando um problema.
  • Mais fácil de rebase, já que cada commit está por conta própria.
  • Mais fácil de dividir ao se deparar com problemas

Contras:

  • Leva mais tempo, pois cada commit deve ser escolhido individualmente.
  • Pouco mais difícil dizer se commit é de upstream à primeira vista

Mesclar

Prós :

  • É mais rápido porque você não precisa esperar que todos os patches limpos sejam mesclados.
  • É mais fácil ver quando um commit é do upstream, já que você não será o committer, o mantenedor do upstream será.

Contras:

  • Resolvendo conflitos pode ser um pouco mais difícil, pois você precisará procurar qual commit está causando o conflito usando git log / git blame, ele não lhe dirá diretamente.
  • Rebasing é difícil, como você não pode rebase uma mesclagem, ele oferecerá para cherry-pick todos os commit individualmente. No entanto, você não deve estar rebaixando frequentemente, em vez disso, usando git revert e git merge, sempre que possível.

Eu recomendaria fazer um cherry-pick para descobrir quaisquer conflitos de problemas inicialmente, fazendo uma mesclagem, e depois reverter os commits do problema posteriormente, assim a atualização é mais fácil (já que a fusão é mais rápida depois de estar atualizada).

Adicione os commits à sua fonte, uma versão de cada vez

A parte mais importante desse processo é a parte de uma versão por vez. Pode haver um patch com problema em sua série upstream, o que poderia causar um problema com a inicialização ou quebrar algo como som ou carregamento (explicado na seção de dicas e truques). Fazer alterações de versão incremental é importante por esse motivo, é mais fácil encontrar um problema em 50 commits do que em upwards de 2000 em algumas versões. Eu recomendaria apenas fazer uma mesclagem completa quando você conhecer todos os problemas e resoluções de conflitos.

Apanhar cerejas

Formato:

 git cherry-pick .. 

Exemplo:

git cherry-pick v3.10.73..v3.10.74

Mesclar

Formato:

 git merge 

Exemplo:

git merge v3.10.74

Eu recomendo manter o controle dos conflitos em commits de mesclagem removendo os # marcadores.

Como resolver conflitos

Não podemos fornecer um guia passo-a-passo para resolver todos os conflitos, pois envolve um bom conhecimento da linguagem C, mas aqui estão algumas dicas.

Se você estiver mesclando, descubra qual commit está causando o conflito. Você pode fazer isso de duas maneiras:

  1. git log -pv $ (make kernelversion) .. para obter as alterações entre sua versão atual e a mais recente do upstream. O sinalizador -p fornecerá as alterações feitas por cada confirmação para que você possa ver.
  2. Execute git blame no arquivo para obter os hashes de cada commit na área. Você pode então executar git show –format = fuller para ver se o committer era de mainline / stable, Google ou CodeAurora.
  • Descobrir se você já tem o commit. Alguns fornecedores, como o Google ou o CAF, tentam buscar defeitos críticos no upstream, como a correção Dirty COW, e seus backports podem entrar em conflito com o upstream. Você pode executar git log –grep = ”” e ver se ele retorna alguma coisa. Em caso afirmativo, você pode pular o commit (se escolher com git reset –hard && git cherry-pick –continue) ou ignorar os conflitos (remova o <<<<< >>>>>).
  • Descobrir se houve um backport que está bagunçando a resolução. O Google e a CAF gostam de retroceder certos patches que o stable não faria. Estável, muitas vezes, precisará adaptar a resolução do commit da linha principal à ausência de certos patches que o Google opta por backport. Você pode olhar para o mainline commit executando git show (o hash da linha principal estará disponível na mensagem de commit do commit estável). Se houver um backport atrapalhando, você pode descartar as alterações ou usar a versão mainline (que é o que você normalmente precisará fazer).
  • Leia o que o commit está tentando fazer e veja se o problema já está corrigido. Às vezes, o CAF pode corrigir um bug independente do upstream, o que significa que você pode sobrescrever sua correção para o upstream ou descartá-lo, como acima.

Caso contrário, pode ser apenas o resultado de uma adição ao CAF / Google / OEM, caso em que você só precisa alterar algumas coisas.

Aqui está um espelho do repositório kernel.org estável em linux no GitHub, que pode ser mais fácil para procurar listas de commits e diffs para resolução de conflitos. Eu recomendo ir primeiro para a lista de commits e localizar o commit do problema para ver o diff original para compará-lo ao seu.

Exemplo de URL: //github.com/nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c

Você também pode fazer isso por meio da linha de comando:

 git log .. git show 

Resolver resoluções é tudo sobre contexto. O que você DEVE SEMPRE fazer é certificar-se de que seu diff final corresponde ao upstream executando os seguintes comandos em duas janelas separadas:

 git diff HEAD git diff v $ (faça o kernelversion) .. $ (git tag --sort = -taggerdate -lv $ (faça o kernelversion | corte -d. -f 1, 2) * | cabeça -n1) 

Ativar rerere

O Git possui um recurso chamado rerere (significa Reuse Recorded Resolution), o que significa que quando ele detecta um conflito, ele registra como você o resolveu para que você possa reutilizá-lo mais tarde. Isso é especialmente útil para ambos os rebasers crônicos, tanto com a fusão quanto com o cherry-picking, pois você só precisará executar o git add. && git –continuar ao refazer a ativação upstream, pois o conflito será resolvido como você o resolveu anteriormente.

Ele pode ser ativado executando o seguinte comando no repositório do kernel:

 git config rerere.enabled true 

Como git bissect quando executando em um compilador ou erro de execução

Dado que você estará adicionando um número considerável de commits, é muito possível que você introduza um compilador ou erro de execução. Em vez de simplesmente desistir, você pode usar a ferramenta de bissetriz integrada do git para descobrir a causa raiz do problema! Idealmente, você estará construindo e piscando cada versão do kernel, à medida que você o adiciona, então a separação dependerá menos, se necessário, mas você pode separar 5000 commits sem quaisquer problemas.

O que o git bisect fará é tomar uma série de commits, de onde o problema está presente para o local onde ele não estava presente, e então começar a reduzir o intervalo de commit, permitindo que você construa e teste e informe se está bom ou não . Ele continuará assim até que o commit cause o seu problema. Nesse ponto, você pode corrigi-lo ou revertê-lo.

  1. Comece a dividir: git bisect start
  2. Rotular a revisão atual como ruim: git bisect bad
  3. Rotule uma revisão como boa: git bisect good
  4. Construa com a nova revisão
  5. Com base no resultado (se o problema estiver presente ou não), diga git: git bisect good OU git bisect bad
  6. Lave e repita os passos 4-5 até que o problema seja confirmado!
  7. Reverter ou corrigir o commit do problema.

OBSERVAÇÃO: As fusões precisarão executar temporariamente o git rebase -i para aplicar todas as correções à sua ramificação para divisão adequada, já que a divisão com as mesclagens no local geralmente fará o checkout nos commits upstream, significando que você não possui nenhuma das confirmações específicas do Android. Eu posso entrar em mais profundidade sobre isso a pedido, mas confie em mim, é necessário. Depois de identificar o commit do problema, você pode reverter ou rebase-lo na mesclagem.

NÃO esmague atualizações upstream

Muitos novos desenvolvedores são tentados a fazer isso, pois é “mais limpo” e “mais fácil” de gerenciar. Isso é terrível por alguns motivos:

  • Autoria está perdida. É injusto para outros desenvolvedores ter seu crédito roubado pelo seu trabalho.
  • A divisão é impossível. Se você esmagar uma série de commits e algo for um problema nessa série, é impossível dizer qual commit causou um problema em uma squash.
  • As futuras escolhas de cereja são mais difíceis. Se você precisar rebase com uma série esmagada, é difícil / impossível dizer de onde resulta um conflito.

Assine a lista de discussão Linux Kernel para atualizações oportunas

Para ser notificado sempre que houver uma atualização do upstream, assine a lista linux-kernel-announce. Isso permitirá que você receba um e-mail sempre que um novo kernel for lançado, para que você possa atualizá-lo e enviá-lo o mais rápido possível.

Artigos Interessantes