Monitoramento de ABI do kernel Android

Você pode usar as ferramentas de monitoramento de interface binária (ABI) do aplicativo, disponíveis no Android 11 e versões posteriores, para estabilizar a ABI no kernel dos kernels do Android. As ferramentas coletam e comparam representações ABI de binários de kernel existentes (módulos vmlinux + GKI). Essas representações ABI são os arquivos .stg e as listas de símbolos. A interface na qual a representação fornece uma visão é chamada de Kernel Module Interface (KMI). Você pode usar as ferramentas para rastrear e mitigar alterações no KMI.

A ferramenta de monitoramento ABI é desenvolvida em AOSP e usa STG (ou libabigail no Android 13 e inferior) para gerar e comparar representações.

Esta página descreve as ferramentas, o processo de coleta e análise de representações da ABI e o uso de tais representações para fornecer estabilidade à ABI no kernel. Esta página também fornece informações para contribuir com alterações nos kernels do Android.

Processo

A análise da ABI do kernel envolve várias etapas, a maioria das quais pode ser automatizada:

  1. Construa o kernel e sua representação ABI .
  2. Analise as diferenças de ABI entre a compilação e uma referência .
  3. Atualize a representação da ABI (se necessário) .
  4. Trabalhe com listas de símbolos .

As instruções a seguir funcionam para qualquer kernel que você possa construir usando uma cadeia de ferramentas suportada (como a cadeia de ferramentas Clang pré-construída). repo manifests estão disponíveis para todas as ramificações comuns do kernel do Android e para vários kernels específicos do dispositivo. Eles garantem que o conjunto de ferramentas correto seja usado quando você cria uma distribuição de kernel para análise.

Listas de símbolos

O KMI não inclui todos os símbolos do kernel ou mesmo todos os mais de 30.000 símbolos exportados. Em vez disso, os símbolos que podem ser usados ​​pelos módulos do fornecedor são explicitamente listados em um conjunto de arquivos de lista de símbolos mantidos publicamente na raiz da árvore do kernel. A união de todos os símbolos em todos os arquivos da lista de símbolos define o conjunto de símbolos KMI mantidos como estáveis. Um exemplo de arquivo de lista de símbolos é abi_gki_aarch64_db845c , que declara os símbolos necessários para o DragonBoard 845c .

Somente os símbolos listados em uma lista de símbolos e suas estruturas e definições relacionadas são considerados parte do KMI. Você pode publicar alterações em suas listas de símbolos se os símbolos necessários não estiverem presentes. Depois que novas interfaces estiverem em uma lista de símbolos e fizerem parte da descrição do KMI, elas serão mantidas como estáveis ​​e não deverão ser removidas da lista de símbolos ou modificadas após o congelamento da ramificação.

Cada ramificação do kernel KMI do Android Common Kernel (ACK) tem seu próprio conjunto de listas de símbolos. Nenhuma tentativa é feita para fornecer estabilidade de ABI entre diferentes ramificações do kernel KMI. Por exemplo, o KMI para android12-5.10 é completamente independente do KMI para android13-5.10 .

As ferramentas ABI usam listas de símbolos KMI para limitar quais interfaces devem ser monitoradas quanto à estabilidade. A lista de símbolos principal contém os símbolos exigidos pelos módulos do kernel GKI. Espera-se que os fornecedores enviem e atualizem listas de símbolos adicionais para garantir que as interfaces nas quais eles dependem mantenham a compatibilidade da ABI. Por exemplo, para ver uma lista de listas de símbolos para android13-5.15 , consulte https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android

Uma lista de símbolos contém os símbolos considerados necessários para o fornecedor ou dispositivo específico. A lista completa utilizada pelas ferramentas é a união de todos os arquivos da lista de símbolos KMI. As ferramentas ABI determinam os detalhes de cada símbolo, incluindo assinatura de função e estruturas de dados aninhadas.

Quando o KMI está congelado, nenhuma alteração é permitida nas interfaces KMI existentes; eles estão estáveis. No entanto, os fornecedores são livres para adicionar símbolos ao KMI a qualquer momento, desde que as adições não afetem a estabilidade da ABI existente. Os símbolos recém-adicionados são mantidos estáveis ​​assim que são citados por uma lista de símbolos KMI. Os símbolos não devem ser removidos de uma lista de um kernel, a menos que seja confirmado que nenhum dispositivo jamais foi enviado com dependência desse símbolo.

Você pode gerar uma lista de símbolos KMI para um dispositivo usando as instruções em Como trabalhar com listas de símbolos . Muitos parceiros enviam uma lista de símbolos por ACK, mas este não é um requisito difícil. Se ajudar na manutenção, você pode enviar várias listas de símbolos.

Estenda o KMI

Embora os símbolos KMI e estruturas relacionadas sejam mantidos estáveis ​​(o que significa que alterações que quebram interfaces estáveis ​​em um kernel com um KMI congelado não podem ser aceitas), o kernel GKI permanece aberto a extensões para que os dispositivos enviados no final do ano não precisem definir todos suas dependências antes que o KMI seja congelado. Para estender o KMI, você pode adicionar novos símbolos ao KMI para funções de kernel exportadas novas ou existentes, mesmo se o KMI estiver congelado. Novos patches de kernel também podem ser aceitos se não quebrarem o KMI.

Sobre quebras de KMI

Um kernel possui fontes e os binários são construídos a partir dessas fontes. As ramificações do kernel monitoradas pela ABI incluem uma representação ABI da ABI GKI atual (na forma de um arquivo .stg ). Após a construção dos binários ( vmlinux , Image e quaisquer módulos GKI), uma representação ABI pode ser extraída dos binários. Qualquer alteração feita em um arquivo fonte do kernel pode afetar os binários e, por sua vez, também afetar o .stg extraído. O analisador AbiAnalyzer compara o arquivo .stg confirmado com aquele extraído dos artefatos de construção e define um rótulo Lint-1 na alteração em Gerrit se encontrar uma diferença semântica.

Lidar com quebras de ABI

Por exemplo, o patch a seguir apresenta uma quebra de ABI muito óbvia:

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 42786e6364ef..e15f1d0f137b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -657,6 +657,7 @@ struct mm_struct {
                ANDROID_KABI_RESERVE(1);
        } __randomize_layout;
 
+       int tickle_count;
        /*
         * The mm_cpumask needs to be at the end of mm_struct, because it
         * is dynamically sized based on nr_cpu_ids.

Quando você executa o build ABI com esse patch aplicado, as ferramentas saem com um código de erro diferente de zero e relatam uma diferença de ABI semelhante a esta:

function symbol 'struct block_device* I_BDEV(struct inode*)' changed
  CRC changed from 0x8d400dbd to 0xabfc92ad

function symbol 'void* PDE_DATA(const struct inode*)' changed
  CRC changed from 0xc3c38b5c to 0x7ad96c0d

function symbol 'void __ClearPageMovable(struct page*)' changed
  CRC changed from 0xf489e5e8 to 0x92bd005e

... 4492 omitted; 4495 symbols have only CRC changes

type 'struct mm_struct' changed
  byte size changed from 992 to 1000
  member 'int tickle_count' was added
  member 'unsigned long cpu_bitmap[0]' changed
    offset changed by 64

Diferenças de ABI detectadas no momento da construção

O motivo mais comum para erros é quando um driver usa um novo símbolo do kernel que não está em nenhuma lista de símbolos.

Se o símbolo não estiver incluído na lista de símbolos ( android/abi_gki_aarch64 ), primeiro você precisará verificar se ele foi exportado com EXPORT_SYMBOL_GPL( symbol_name ) e depois atualizar a representação XML da ABI e a lista de símbolos. Por exemplo, as alterações a seguir adicionam o novo recurso Incremental FS à ramificação android-12-5.10 , que inclui a atualização da lista de símbolos e da representação XML da ABI.

Se o símbolo for exportado (por você ou foi exportado anteriormente), mas nenhum outro driver o estiver usando, você poderá receber um erro de compilação semelhante ao seguinte.

Comparing the KMI and the symbol lists:
+ build/abi/compare_to_symbol_list out/$BRANCH/common/Module.symvers out/$BRANCH/common/abi_symbollist.raw
ERROR: Differences between ksymtab and symbol list detected!
Symbols missing from ksymtab:
Symbols missing from symbol list:
 - simple_strtoull

Para resolver, atualize a lista de símbolos KMI tanto no seu kernel quanto no ACK (veja Atualizar a representação da ABI ). Para obter um exemplo de atualização do XML da ABI e da lista de símbolos no ACK, consulte aosp/1367601 .

Resolver quebras de ABI do kernel

Você pode lidar com quebras de ABI do kernel refatorando o código para não alterar a ABI ou atualizando a representação da ABI . Use o gráfico a seguir para determinar a melhor abordagem para sua situação.

Fluxograma de quebra da ABI

Figura 1. Resolução de quebra de ABI

Refatore o código para evitar alterações na ABI

Faça todos os esforços para evitar modificar a ABI existente. Em muitos casos, você pode refatorar seu código para remover alterações que afetam a ABI.

  • Refatorando alterações no campo struct. Se uma alteração modificar a ABI para um recurso de depuração, adicione um #ifdef ao redor dos campos (nas estruturas e referências de origem) e certifique-se de que o CONFIG usado para o #ifdef esteja desabilitado para a produção defconfig e gki_defconfig . Para obter um exemplo de como uma configuração de depuração pode ser adicionada a uma estrutura sem quebrar a ABI, consulte este patchset .

  • Refatoração de recursos para não alterar o kernel principal. Se novos recursos precisarem ser adicionados ao ACK para oferecer suporte aos módulos parceiros, tente refatorar a parte ABI da mudança para evitar a modificação da ABI do kernel. Para obter um exemplo de uso da ABI do kernel existente para adicionar funcionalidades adicionais sem alterar a ABI do kernel, consulte aosp/1312213 .

Corrija uma ABI quebrada no Android Gerrit

Se você não quebrou intencionalmente a ABI do kernel, será necessário investigar, usando as orientações fornecidas pelas ferramentas de monitoramento da ABI. As causas mais comuns de quebras são alterações nas estruturas de dados e alterações no símbolo CRC associado, ou devido a alterações nas opções de configuração que levam a qualquer um dos itens mencionados acima. Comece abordando os problemas encontrados pela ferramenta.

Você pode reproduzir as descobertas da ABI localmente, consulte Construir o kernel e sua representação da ABI .

Sobre rótulos Lint-1

Se você fizer upload de alterações em uma ramificação contendo um KMI congelado ou finalizado, as alterações deverão passar pelo AbiAnalyzer para garantir que as alterações não afetem a ABI estável de maneira incompatível. Durante esse processo, o AbiAnalyzer procura o relatório ABI criado durante a compilação (uma compilação estendida que executa a compilação normal e, em seguida, algumas etapas de extração e comparação de ABI.

Se o AbiAnalyzer encontrar um relatório não vazio, ele definirá o rótulo Lint-1 e o envio da alteração será bloqueado até ser resolvido; até que o patchset receba um rótulo Lint+1.

Atualizar a ABI do kernel

Se a modificação da ABI for inevitável, você deverá aplicar as alterações de código, a representação da ABI e a lista de símbolos ao ACK. Para fazer com que o Lint remova o -1 e não quebre a compatibilidade do GKI, siga estas etapas:

  1. Carregue as alterações de código no ACK .

  2. Aguarde para receber uma revisão de código +2 para o patchset.

  3. Atualize a representação de referência da ABI .

  4. Mescle suas alterações de código e a alteração de atualização da ABI.

Carregar alterações no código ABI para o ACK

A atualização do ACK ABI depende do tipo de alteração que está sendo feita.

  • Se uma alteração da ABI estiver relacionada a um recurso que afeta os testes CTS ou VTS, a alteração geralmente poderá ser selecionada para ACK como está. Por exemplo:

  • Se uma alteração da ABI for para um recurso que pode ser compartilhado com o ACK, essa alteração poderá ser escolhida a dedo para o ACK como está. Por exemplo, as seguintes alterações não são necessárias para testes CTS ou VTS, mas podem ser compartilhadas com ACK:

  • Se uma alteração da ABI introduzir um novo recurso que não precisa ser incluído no ACK, você poderá introduzir os símbolos no ACK usando um stub conforme descrito na seção a seguir.

Use stubs para ACK

Os stubs devem ser necessários apenas para alterações principais do kernel que não beneficiem o ACK, como alterações de desempenho e energia. A lista a seguir detalha exemplos de stubs e escolhas parciais no ACK para GKI.

  • Stub de recurso de isolamento de núcleo ( aosp/1284493 ). A funcionalidade no ACK não é necessária, mas os símbolos precisam estar presentes no ACK para que seus módulos usem esses símbolos.

  • Símbolo de espaço reservado para módulo de fornecedor ( aosp/1288860 ).

  • Seleção seletiva apenas da ABI do recurso de rastreamento de eventos mm por processo ( aosp/1288454 ). O patch original foi escolhido a dedo para ACK e depois cortado para incluir apenas as alterações necessárias para resolver a diferença de ABI para task_struct e mm_event_count . Este patch também atualiza o enum mm_event_type para conter os membros finais.

  • Seleção parcial de alterações na estrutura térmica da ABI que exigiam mais do que apenas adicionar os novos campos da ABI.

    • O patch aosp/1255544 resolveu diferenças de ABI entre o kernel parceiro e o ACK.

    • O patch aosp/1291018 corrigiu os problemas funcionais encontrados durante o teste GKI do patch anterior. A correção incluiu a inicialização da estrutura do parâmetro do sensor para registrar múltiplas zonas térmicas em um único sensor.

  • CONFIG_NL80211_TESTMODE Alterações de ABI ( aosp/1344321 ). Este patch adicionou as alterações estruturais necessárias para ABI e garantiu que os campos adicionais não causassem diferenças funcionais, permitindo que os parceiros incluíssem CONFIG_NL80211_TESTMODE em seus kernels de produção e ainda mantivessem a conformidade com GKI.

Aplicar o KMI em tempo de execução

Os kernels GKI usam as opções de configuração TRIM_UNUSED_KSYMS=y e UNUSED_KSYMS_WHITELIST=<union of all symbol lists> , que limitam os símbolos exportados (como símbolos exportados usando EXPORT_SYMBOL_GPL() ) àqueles listados em uma lista de símbolos. Todos os outros símbolos não são exportados e o carregamento de um módulo que requer um símbolo não exportado é negado. Essa restrição é aplicada no momento da construção e as entradas ausentes são sinalizadas.

Para fins de desenvolvimento, você pode usar uma compilação de kernel GKI que não inclua corte de símbolos (o que significa que todos os símbolos normalmente exportados podem ser usados). Para localizar essas compilações, procure as compilações kernel_debug_aarch64 em ci.android.com .

Aplicar o KMI usando controle de versão de módulo

Os kernels Generic Kernel Image (GKI) usam controle de versão de módulo ( CONFIG_MODVERSIONS ) como uma medida adicional para impor conformidade com KMI em tempo de execução. O versionamento do módulo pode causar falhas de incompatibilidade na verificação de redundância cíclica (CRC) no tempo de carregamento do módulo se o KMI esperado de um módulo não corresponder ao KMI vmlinux . Por exemplo, a seguir está uma falha típica que ocorre no tempo de carregamento do módulo devido a uma incompatibilidade de CRC para o símbolo module_layout() :

init: Loading module /lib/modules/kernel/.../XXX.ko with args ""
XXX: disagrees about version of symbol module_layout
init: Failed to insmod '/lib/modules/kernel/.../XXX.ko' with args ''

Usos de versionamento de módulo

O controle de versão do módulo é útil pelos seguintes motivos:

  • O versionamento do módulo detecta alterações na visibilidade da estrutura de dados. Se os módulos alterarem estruturas de dados opacas, ou seja, estruturas de dados que não fazem parte do KMI, eles serão interrompidos após alterações futuras na estrutura.

    Como exemplo, considere o campo fwnode em struct device . Este campo DEVE ser opaco para os módulos para que eles não possam fazer alterações nos campos de device->fw_node ou fazer suposições sobre seu tamanho.

    No entanto, se um módulo incluir <linux/fwnode.h> (direta ou indiretamente), então o campo fwnode no struct device não será mais opaco para ele. O módulo pode então fazer alterações em device->fwnode->dev ou device->fwnode->ops . Este cenário é problemático por vários motivos, enunciados a seguir:

    • Ele pode quebrar suposições que o código principal do kernel está fazendo sobre suas estruturas de dados internas.

    • Se uma atualização futura do kernel alterar a struct fwnode_handle (o tipo de dados de fwnode ), então o módulo não funcionará mais com o novo kernel. Além disso, stgdiff não mostrará nenhuma diferença porque o módulo está quebrando o KMI ao manipular diretamente estruturas de dados internas de maneiras que não podem ser capturadas apenas inspecionando a representação binária.

  • Um módulo atual é considerado incompatível com KMI quando é carregado posteriormente por um novo kernel incompatível. O versionamento de módulo adiciona uma verificação em tempo de execução para evitar o carregamento acidental de um módulo que não seja compatível com KMI com o kernel. Essa verificação evita problemas de tempo de execução difíceis de depurar e falhas de kernel que podem resultar de uma incompatibilidade não detectada no KMI.

Habilitar o versionamento de módulos evita todos esses problemas.

Verifique se há incompatibilidades de CRC sem inicializar o dispositivo

stgdiff compara e relata incompatibilidades de CRC entre kernels junto com outras diferenças de ABI.

Além disso, uma compilação completa do kernel com CONFIG_MODVERSIONS habilitado gera um arquivo Module.symvers como parte do processo normal de compilação. Este arquivo possui uma linha para cada símbolo exportado pelo kernel ( vmlinux ) e pelos módulos. Cada linha consiste no valor CRC, no nome do símbolo, no namespace do símbolo, no vmlinux ou no nome do módulo que está exportando o símbolo e no tipo de exportação (por exemplo, EXPORT_SYMBOL versus EXPORT_SYMBOL_GPL ).

Você pode comparar os arquivos Module.symvers entre a compilação do GKI e a sua compilação para verificar se há diferenças de CRC nos símbolos exportados por vmlinux . Se houver uma diferença no valor CRC em qualquer símbolo exportado pelo vmlinux e esse símbolo for usado por um dos módulos que você carrega no seu dispositivo, o módulo não carrega.

Se você não tiver todos os artefatos de compilação, mas tiver os arquivos vmlinux do kernel GKI e do seu kernel, poderá comparar os valores CRC para um símbolo específico executando o seguinte comando em ambos os kernels e comparando a saída:

nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>

Por exemplo, o comando a seguir verifica o valor CRC do símbolo module_layout :

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Resolver incompatibilidades de CRC

Use as etapas a seguir para resolver uma incompatibilidade de CRC ao carregar um módulo:

  1. Crie o kernel GKI e o kernel do seu dispositivo usando a opção --kbuild_symtypes conforme mostrado no comando a seguir:

    tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
    

    Este comando gera um arquivo .symtypes para cada arquivo .o . Consulte KBUILD_SYMTYPES no Kleaf para obter detalhes.

    Para Android 13 e versões anteriores, crie o kernel GKI e o kernel do seu dispositivo acrescentando KBUILD_SYMTYPES=1 ao comando usado para criar o kernel, conforme mostrado no comando a seguir:

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

    Ao usar build_abi.sh, o sinalizador KBUILD_SYMTYPES=1 já está definido implicitamente.

  2. Encontre o arquivo .c no qual o símbolo com incompatibilidade de CRC é exportado, usando o seguinte comando:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. O arquivo .c possui um arquivo .symtypes correspondente no GKI e os artefatos de compilação do kernel do seu dispositivo. Localize o arquivo .c usando os seguintes comandos:

    cd out/$BRANCH/common && ls -1 kernel/module.*
    kernel/module.o
    kernel/module.o.symversions
    kernel/module.symtypes
    

    A seguir estão as características do arquivo .c :

    • O formato do arquivo .c é uma linha (potencialmente muito longa) por símbolo.

    • [s|u|e|etc]# no início da linha significa que o símbolo é do tipo de dados [struct|union|enum|etc] . Por exemplo:

      t#bool typedef _Bool bool
      
    • Um prefixo # ausente no início da linha indica que o símbolo é uma função. Por exemplo:

      find_module s#module * find_module ( const char * )
      
  4. Compare os dois arquivos e corrija todas as diferenças.

Caso 1: Diferenças devido à visibilidade do tipo de dados

Se um kernel mantiver um símbolo ou tipo de dados opaco para os módulos e o outro kernel não, essa diferença aparecerá entre os arquivos .symtypes dos dois kernels. O arquivo .symtypes de um dos kernels possui UNKNOWN para um símbolo e o arquivo .symtypes do outro kernel possui uma visão expandida do símbolo ou tipo de dados.

Por exemplo, adicionar a seguinte linha ao arquivo include/linux/device.h em seu kernel causa incompatibilidades de CRC, uma das quais é para module_layout() :

 #include <linux/fwnode.h>

Comparar module.symtypes para esse símbolo expõe as seguintes diferenças:

 $ diff -u <GKI>/kernel/module.symtypes <your kernel>/kernel/module.symtypes
  --- <GKI>/kernel/module.symtypes
  +++ <your kernel>/kernel/module.symtypes
  @@ -334,12 +334,15 @@
  ...
  -s#fwnode_handle struct fwnode_handle { UNKNOWN }
  +s#fwnode_reference_args struct fwnode_reference_args { s#fwnode_handle * fwnode ; unsigned int nargs ; t#u64 args [ 8 ] ; }
  ...

Se o seu kernel tiver um valor UNKNOWN e o kernel GKI tiver a visualização expandida do símbolo (muito improvável), mescle o Android Common Kernel mais recente em seu kernel para que você use a base de kernel GKI mais recente.

Na maioria dos casos, o kernel GKI tem um valor UNKNOWN , mas seu kernel possui os detalhes internos do símbolo devido às alterações feitas em seu kernel. Isso ocorre porque um dos arquivos do seu kernel adicionou um #include que não está presente no kernel do GKI.

Muitas vezes, a correção é tão simples quanto ocultar o novo #include do genksyms .

#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif

Caso contrário, para identificar o #include que causa a diferença, siga estes passos:

  1. Abra o arquivo de cabeçalho que define o símbolo ou tipo de dados com essa diferença. Por exemplo, edite include/linux/fwnode.h para a struct fwnode_handle .

  2. Adicione o seguinte código no topo do arquivo de cabeçalho:

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. No arquivo .c do módulo que possui uma incompatibilidade de CRC, adicione o seguinte como a primeira linha antes de qualquer uma das linhas #include .

    #define CRC_CATCH 1
    
  4. Compile seu módulo. O erro em tempo de compilação resultante mostra a cadeia do arquivo de cabeçalho #include que levou a essa incompatibilidade de CRC. Por exemplo:

    In file included from .../drivers/clk/XXX.c:16:`
    In file included from .../include/linux/of_device.h:5:
    In file included from .../include/linux/cpu.h:17:
    In file included from .../include/linux/node.h:18:
    .../include/linux/device.h:16:2: error: "Included from here"
    #error "Included from here"
    

    Um dos elos desta cadeia de #include se deve a uma alteração feita em seu kernel, que está faltando no kernel GKI.

  5. Identifique a alteração, reverta-a em seu kernel ou carregue-a no ACK e faça a mesclagem .

Caso 2: Diferenças devido a alterações no tipo de dados

Se a incompatibilidade de CRC para um símbolo ou tipo de dados não for devido a uma diferença na visibilidade, será devido a alterações reais (adições, remoções ou alterações) no próprio tipo de dados.

Por exemplo, fazer a seguinte alteração em seu kernel causa diversas incompatibilidades de CRC, pois muitos símbolos são afetados indiretamente por esse tipo de alteração:

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -259,7 +259,7 @@ struct iommu_ops {
     void (*iotlb_sync)(struct iommu_domain *domain);
     phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
     phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
  -        dma_addr_t iova);
  +        dma_addr_t iova, unsigned long trans_flag);
     int (*add_device)(struct device *dev);
     void (*remove_device)(struct device *dev);
     struct iommu_group *(*device_group)(struct device *dev);

Uma incompatibilidade de CRC é para devm_of_platform_populate() .

Se você comparar os arquivos .symtypes desse símbolo, ele poderá ficar assim:

 $ diff -u <GKI>/drivers/of/platform.symtypes <your kernel>/drivers/of/platform.symtypes
  --- <GKI>/drivers/of/platform.symtypes
  +++ <your kernel>/drivers/of/platform.symtypes
  @@ -399,7 +399,7 @@
  ...
  -s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t ) ; int
    ( * add_device ) ( s#device * ) ; ...
  +s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t , unsigned long ) ; int ( * add_device ) ( s#device * ) ; ...

Para identificar o tipo alterado, siga estas etapas:

  1. Encontre a definição do símbolo no código-fonte (geralmente em arquivos .h ).

    • Para diferenças simples de símbolos entre seu kernel e o kernel GKI, encontre o commit executando o seguinte comando:
    git blame
    
    • Para símbolos excluídos (onde um símbolo é excluído em uma árvore e você também deseja excluí-lo na outra árvore), você precisa encontrar a alteração que excluiu a linha. Use o seguinte comando na árvore onde a linha foi excluída:
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. Revise a lista de confirmações retornada para localizar a alteração ou exclusão. O primeiro commit é provavelmente aquele que você está procurando. Caso contrário, percorra a lista até encontrar o commit.

  3. Depois de identificar a alteração, reverta-a em seu kernel ou carregue-a no ACK e faça a mesclagem .