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 superior, para estabilizar a ABI no kernel dos kernels do Android. As ferramentas coletam e comparam representações ABI de binários de kernel existentes ( vmlinux + módulos). Essas representações ABI são os arquivos .stg e as listas de símbolos. A interface na qual a representação fornece uma exibição é chamada de Kernel Module Interfaces (KMIs). 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 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 ABI (se necessário) .
  4. Trabalhar 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 de kernel comuns do Android e para vários kernels específicos do dispositivo, eles garantem que a cadeia de ferramentas correta seja usada quando você cria uma distribuição de kernel para análise.

listas de símbolos

A KMI não inclui todos os símbolos no 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 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 de 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 postar alterações em suas listas de símbolos se os símbolos necessários não estiverem presentes. Após novas interfaces estarem em uma lista de símbolos e fazerem parte da descrição KMI, elas são mantidas como estáveis ​​e não devem 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 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 para estabilidade. A lista principal de símbolos 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 com 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 relatados como necessários para o fornecedor ou dispositivo específico. A lista completa utilizada pelas ferramentas é a união de todos os arquivos de 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 para um kernel, a menos que possa ser confirmado que nenhum dispositivo já foi enviado com uma dependência desse símbolo.

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

Estender o KMI

Embora os símbolos KMI e as estruturas relacionadas sejam mantidos como estáveis ​​(o que significa que as alterações que quebram as 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 todas as 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 são aceitos se não quebrarem o KMI.

Sobre quebras de KMI

Um kernel tem fontes e um binário é construído com base nessas fontes. As ramificações do kernel monitoradas pela ABI incluem abi.xml , que é uma representação da GKI ABI atual. Depois que o binário é criado (o binário do kernel, vmlinux , Image mais os módulos do kernel), um arquivo abi.xml pode ser extraído dos binários. Qualquer alteração feita em uma origem do kernel pode alterar o binário e também alterar o abi.xml extraído (o arquivo que é extraído após aplicar a alteração e construir o kernel). O analisador AbiAnalyzer compara os dois arquivos abi.xml semanticamente e define um rótulo Lint-1 na alteração se encontrar um problema.

Lidar com quebras de ABI

Como 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 5ed8f6292a53..f2ecb34c7645 100644
  --- a/include/linux/mm_types.h
  +++ b/include/linux/mm_types.h
  @@ -339,6 +339,7 @@ struct core_state {
   struct kioctx_table;
   struct mm_struct {
      struct {
  +       int dummy;
          struct vm_area_struct *mmap;            /* list of VMAs */
          struct rb_root mm_rb;
          u64 vmacache_seqnum;                   /* per-thread vmacache */

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

 Leaf changes summary: 1 artifact changed
  Changed leaf types summary: 1 leaf type changed
  Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added function
  Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable

  'struct mm_struct at mm_types.h:372:1' changed:
    type size changed from 6848 to 6912 (in bits)
    there are data member changes:
  [...]

Diferenças de ABI detectadas no tempo de compilação

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

Se o símbolo não estiver incluído na lista de símbolos ( android/abi_gki_aarch64 ), você precisará primeiro verificar se ele foi exportado com EXPORT_SYMBOL_GPL( symbol_name ) e, em seguida, atualizar a representação XML 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 a representação ABI XML.

Se o símbolo for exportado (por você ou foi exportado anteriormente), mas nenhum outro driver o estiver usando no momento, você poderá obter 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 em seu kernel e no ACK (consulte Atualizar a representação ABI ). Para obter um exemplo de atualização do ABI XML 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 a tabela a seguir para determinar a melhor abordagem para sua situação.

Fluxograma de Quebra ABI

Figura 1. Resolução de quebra ABI

Refatore o código para evitar alterações de 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 de 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 o defconfig e gki_defconfig de produção. 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 .

  • Recursos de refatoração para não alterar o núcleo do kernel. Se novos recursos precisarem ser adicionados ao ACK para dar suporte aos módulos parceiros, tente refatorar a parte ABI da mudança para evitar modificar a ABI do kernel. Para obter um exemplo de como usar a ABI do kernel existente para adicionar funcionalidade adicional 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, precisará investigar, usando as orientações fornecidas pelas ferramentas de monitoramento da ABI. As causas mais comuns de quebras são funções adicionadas ou excluídas, estruturas de dados alteradas ou alterações na ABI causadas pela adição de 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 os rótulos Lint-1

Se você carregar alterações em uma ramificação que contém 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 este 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 da ABI. Se o ABIAnalyzer encontrar um relatório não vazio, ele definirá o rótulo Lint-1 e a alteração é bloqueada para envio até ser resolvida; até que o patchset receba um rótulo Lint+1.

Atualize a ABI do Kernel

Se a modificação da ABI for inevitável, você deve 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 interrompa a compatibilidade do GKI, siga estas etapas:

  1. Carregar alterações de código para o ACK .

  2. Aguarde para receber um Code-Review +2 para o patchset.

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

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

Carregar alterações de 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 de ABI estiver relacionada a um recurso que afeta os testes CTS ou VTS, a alteração geralmente pode ser escolhida a dedo para ACK como está. Por exemplo:

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

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

Usar stubs para ACK

Os stubs devem ser necessários apenas para alterações no núcleo do kernel que não beneficiam o ACK, como alterações de desempenho e energia. A lista a seguir detalha exemplos de stubs e seleções parciais em 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 o módulo do fornecedor ( aosp/1288860 ).

  • Escolha seletiva somente ABI do recurso de rastreamento de eventos mm por processo ( aosp/1288454 ). O patch original foi escolhido a dedo para ACK e, em seguida, ajustado para incluir apenas as alterações necessárias para resolver o diff ABI para task_struct e mm_event_count . Este patch também atualiza a enumeração mm_event_type para conter os membros finais.

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

    • O patch aosp/1255544 resolveu as 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 inicializar a estrutura do parâmetro do sensor para registrar várias zonas térmicas em um único sensor.

  • CONFIG_NL80211_TESTMODE Alterações ABI ( aosp/1344321 ). Este patch adicionou as mudanças struct 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() ) aos 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 é imposta no tempo de compilação e as entradas ausentes são sinalizadas.

Para propósitos de desenvolvimento, você pode usar uma compilação de kernel GKI que não inclua o 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 o controle de versão do módulo

Os kernels Generic Kernel Image (GKI) usam o controle de versão do módulo ( CONFIG_MODVERSIONS ) como uma medida adicional para reforçar a conformidade do KMI no tempo de execução. A versão do módulo pode causar falhas de incompatibilidade de verificação de redundância cíclica (CRC) no tempo de carregamento do módulo se a KMI esperada de um módulo não corresponder à KMI do vmlinux . Por exemplo, o seguinte é 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 do controle de versão do módulo

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

  • O controle de versão 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), 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, descritos a seguir:

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

    • Se uma atualização futura do kernel alterar o struct fwnode_handle (o tipo de dados de fwnode ), o módulo não funcionará mais com o novo kernel. Além disso, abidiff não mostrará nenhuma diferença porque o módulo está quebrando o KMI manipulando diretamente as 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 controle de versão do 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 travamentos do kernel que podem resultar de uma incompatibilidade não detectada na KMI.

  • abidiff tem limitações na identificação de diferenças de ABI em certos casos complicados que CONFIG_MODVERSIONS pode capturar.

Habilitar o controle de versão do módulo evita todos esses problemas.

Verifique se há incompatibilidades de CRC sem inicializar o dispositivo

abidiff compara e relata incompatibilidades de CRC entre kernels. Essa ferramenta permite detectar incompatibilidades de CRC ao mesmo tempo que outras diferenças de ABI.

Além disso, uma compilação completa do kernel com CONFIG_MODVERSIONS ativado 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 os módulos. Cada linha consiste no valor CRC, nome do símbolo, namespace do símbolo, vmlinux ou nome do módulo que está exportando o símbolo e o tipo de exportação (por exemplo, EXPORT_SYMBOL versus EXPORT_SYMBOL_GPL ).

Você pode comparar os arquivos Module.symvers entre a compilação GKI e sua compilação para verificar quaisquer diferenças de CRC nos símbolos exportados por vmlinux . Se houver uma diferença de valor CRC em algum símbolo exportado pelo vmlinux e esse símbolo for usado por um dos módulos que você carrega em 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 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 seguinte comando verifica o valor CRC para o 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 dispositivo usando a opção --kbuild_symtypes conforme mostrado no seguinte comando:

    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 dispositivo anexando KBUILD_SYMTYPES=1 ao comando que você usa para criar o kernel, conforme mostrado no seguinte comando:

    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 tem um arquivo .symtypes correspondente no GKI e os artefatos de compilação do kernel do 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 tem UNKNOWN para um símbolo e o arquivo .symtypes do outro kernel tem uma visão expandida do símbolo ou tipo de dado.

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>

A comparação dos module.symtypes desse 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 de UNKNOWN e o kernel GKI tiver a visão expandida do símbolo (muito improvável), mescle o Android Common Kernel mais recente em seu kernel para que você esteja usando a base do kernel GKI mais recente.

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

Para identificar o #include que causa a diferença, siga estas etapas:

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

  2. Adicione o seguinte código na parte superior 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 de 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 links nesta cadeia de #include é devido 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 o merge .

Caso 2: Diferenças devido a mudanças 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, é devido a alterações reais (adições, remoções ou alterações) no próprio tipo de dados. Normalmente, abidiff detecta isso, mas se perder algum devido a lacunas de detecção conhecidas, o mecanismo MODVERSIONS pode detectá-lo.

Por exemplo, fazer a seguinte alteração em seu kernel causa várias incompatibilidades de CRC, pois muitos símbolos são indiretamente afetados 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 pode ter a seguinte aparência:

 $ 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 de símbolo simples entre seu kernel e o kernel GKI, localize 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 deletada:
    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. Se não estiver, 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 o merge .