Monitoreo ABI del kernel de Android

Puede utilizar las herramientas de monitoreo de interfaz binaria (ABI) de la aplicación, disponibles en Android 11 y versiones posteriores, para estabilizar la ABI interna de los kernels de Android. Las herramientas recopilan y comparan representaciones ABI de archivos binarios del kernel existentes (módulos vmlinux + GKI). Estas representaciones ABI son los archivos .stg y las listas de símbolos. La interfaz en la que la representación ofrece una vista se llama Interfaz del módulo kernel (KMI). Puede utilizar las herramientas para realizar un seguimiento y mitigar los cambios en el KMI.

La herramienta de monitoreo ABI está desarrollada en AOSP y utiliza STG (o libabigail en Android 13 y versiones anteriores) para generar y comparar representaciones.

Esta página describe las herramientas, el proceso de recopilación y análisis de representaciones ABI y el uso de dichas representaciones para proporcionar estabilidad a la ABI interna. Esta página también proporciona información para contribuir con cambios en los kernels de Android.

Proceso

El análisis del ABI del kernel requiere varios pasos, la mayoría de los cuales pueden automatizarse:

  1. Construya el kernel y su representación ABI .
  2. Analice las diferencias ABI entre la compilación y una referencia .
  3. Actualice la representación de ABI (si es necesario) .
  4. Trabajar con listas de símbolos .

Las siguientes instrucciones funcionan para cualquier kernel que pueda compilar utilizando una cadena de herramientas compatible (como la cadena de herramientas Clang precompilada). repo manifests están disponibles para todas las ramas comunes del kernel de Android y para varios kernels específicos del dispositivo, garantizan que se utilice la cadena de herramientas correcta cuando se crea una distribución del kernel para su análisis.

Listas de símbolos

El KMI no incluye todos los símbolos del kernel ni siquiera los más de 30.000 símbolos exportados. En cambio, los símbolos que pueden utilizar los módulos del proveedor se enumeran explícitamente en un conjunto de archivos de lista de símbolos mantenidos públicamente en la raíz del árbol del núcleo. La unión de todos los símbolos en todos los archivos de lista de símbolos define el conjunto de símbolos KMI que se mantienen como estables. Un archivo de lista de símbolos de ejemplo es abi_gki_aarch64_db845c , que declara los símbolos necesarios para DragonBoard 845c .

Sólo los símbolos enumerados en una lista de símbolos y sus estructuras y definiciones relacionadas se consideran parte del KMI. Puede publicar cambios en sus listas de símbolos si los símbolos que necesita no están presentes. Una vez que las nuevas interfaces están en una lista de símbolos y forman parte de la descripción de KMI, se mantienen como estables y no deben eliminarse de la lista de símbolos ni modificarse después de que se congele la rama.

Cada rama del kernel KMI de Android Common Kernel (ACK) tiene su propio conjunto de listas de símbolos. No se intenta proporcionar estabilidad ABI entre diferentes ramas del kernel KMI. Por ejemplo, el KMI para android12-5.10 es completamente independiente del KMI para android13-5.10 .

Las herramientas ABI utilizan listas de símbolos KMI para limitar qué interfaces deben monitorearse para determinar su estabilidad. La lista de símbolos principal contiene los símbolos que requieren los módulos del kernel de GKI. Se espera que los proveedores envíen y actualicen listas de símbolos adicionales para garantizar que las interfaces en las que confían mantengan la compatibilidad con ABI. Por ejemplo, para ver una lista de listas de símbolos para android13-5.15 , consulte https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android

Una lista de símbolos contiene los símbolos que, según se informa, son necesarios para un proveedor o dispositivo en particular. La lista completa utilizada por las herramientas es la unión de todos los archivos de lista de símbolos KMI. Las herramientas ABI determinan los detalles de cada símbolo, incluida la firma de función y las estructuras de datos anidadas.

Cuando el KMI está congelado, no se permiten cambios en las interfaces KMI existentes; están estables. Sin embargo, los proveedores son libres de agregar símbolos al KMI en cualquier momento, siempre y cuando las adiciones no afecten la estabilidad de la ABI existente. Los símbolos recién agregados se mantienen estables tan pronto como son citados en una lista de símbolos KMI. Los símbolos no deben eliminarse de una lista para un kernel a menos que se pueda confirmar que ningún dispositivo se ha enviado con una dependencia de ese símbolo.

Puede generar una lista de símbolos KMI para un dispositivo siguiendo las instrucciones de Cómo trabajar con listas de símbolos . Muchos socios envían una lista de símbolos por ACK, pero este no es un requisito estricto. Si ayuda con el mantenimiento, puede enviar varias listas de símbolos.

Ampliar el KMI

Si bien los símbolos KMI y las estructuras relacionadas se mantienen estables (lo que significa que no se pueden aceptar cambios que rompan las interfaces estables en un kernel con un KMI congelado), el kernel GKI permanece abierto a extensiones para que los dispositivos que se envíen más adelante en el año no necesiten definir todos sus dependencias antes de que se congele el KMI. Para ampliar el KMI, puede agregar nuevos símbolos al KMI para funciones del kernel exportadas nuevas o existentes, incluso si el KMI está congelado. También se pueden aceptar nuevos parches del kernel si no dañan el KMI.

Acerca de las roturas de KMI

Un kernel tiene fuentes y los binarios se crean a partir de esas fuentes. Las ramas del kernel supervisadas por ABI incluyen una representación ABI de la ABI de GKI actual (en forma de archivo .stg ). Una vez creados los binarios ( vmlinux , Image y cualquier módulo GKI), se puede extraer una representación ABI de los binarios. Cualquier cambio realizado en un archivo fuente del kernel puede afectar los archivos binarios y, a su vez, también afectar el .stg extraído. El analizador AbiAnalyzer compara el archivo .stg comprometido con el extraído de los artefactos de compilación y establece una etiqueta Lint-1 en el cambio en Gerrit si encuentra una diferencia semántica.

Manejar roturas ABI

Como ejemplo, el siguiente parche introduce una rotura ABI muy obvia:

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.

Cuando ejecuta la compilación ABI con este parche aplicado, las herramientas salen con un código de error distinto de cero e informan una diferencia de ABI similar 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

Diferencias de ABI detectadas en el momento de la compilación

La razón más común de errores es cuando un controlador usa un nuevo símbolo del kernel que no está en ninguna de las listas de símbolos.

Si el símbolo no está incluido en la lista de símbolos ( android/abi_gki_aarch64 ), primero debe verificar que se haya exportado con EXPORT_SYMBOL_GPL( symbol_name ) y luego actualizar la representación XML de ABI y la lista de símbolos. Por ejemplo, los siguientes cambios agregan la nueva función Incremental FS a la rama android-12-5.10 , que incluye la actualización de la lista de símbolos y la representación XML de ABI.

  • El ejemplo de cambio de funciones se encuentra en aosp/1345659 .
  • El ejemplo de la lista de símbolos está en aosp/1346742 .
  • El ejemplo de cambio de XML de ABI se encuentra en aosp/1349377 .

Si el símbolo se exporta (ya sea por usted o se exportó previamente) pero ningún otro controlador lo utiliza, es posible que obtenga un error de compilación similar al siguiente.

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 resolverlo, actualice la lista de símbolos KMI tanto en su kernel como en el ACK (consulte Actualizar la representación ABI ). Para ver un ejemplo de actualización del XML de ABI y la lista de símbolos en el ACK, consulte aosp/1367601 .

Resolver roturas de ABI del kernel

Puede manejar las roturas de la ABI del kernel refactorizando el código para no cambiar la ABI o actualizando la representación de la ABI . Utilice el siguiente cuadro para determinar el mejor enfoque para su situación.

Diagrama de flujo de rotura ABI

Figura 1. Resolución de rotura del ABI

Refactorizar el código para evitar cambios en ABI

Haga todo lo posible para evitar modificar la ABI existente. En muchos casos, puedes refactorizar tu código para eliminar los cambios que afectan la ABI.

  • Refactorización de cambios en el campo de estructura. Si un cambio modifica la ABI para una función de depuración, agregue un #ifdef alrededor de los campos (en las estructuras y referencias de origen) y asegúrese de que la CONFIG utilizada para #ifdef esté deshabilitada para defconfig y gki_defconfig de producción. Para ver un ejemplo de cómo se puede agregar una configuración de depuración a una estructura sin romper la ABI, consulte este conjunto de parches .

  • Funciones de refactorización para no cambiar el núcleo central. Si es necesario agregar nuevas funciones a ACK para admitir los módulos asociados, intente refactorizar la parte ABI del cambio para evitar modificar la ABI del kernel. Para ver un ejemplo del uso de la ABI del kernel existente para agregar funcionalidad adicional sin cambiar la ABI del kernel, consulte aosp/1312213 .

Reparar un ABI roto en Android Gerrit

Si no rompió intencionalmente la ABI del kernel, entonces debe investigar utilizando la guía proporcionada por las herramientas de monitoreo de ABI. Las causas más comunes de roturas son cambios en las estructuras de datos y cambios en el símbolo CRC asociado, o debido a cambios en las opciones de configuración que conducen a cualquiera de los mencionados anteriormente. Comience abordando los problemas encontrados por la herramienta.

Puede reproducir los hallazgos de ABI localmente; consulte Compilación del kernel y su representación ABI .

Acerca de las etiquetas Lint-1

Si carga cambios en una rama que contiene una KMI congelada o finalizada, los cambios deben pasar el AbiAnalyzer para garantizar que no afecten la ABI estable de una manera incompatible. Durante este proceso, AbiAnalyzer busca el informe ABI que se crea durante la compilación (una compilación extendida que realiza la compilación normal y luego algunos pasos de extracción y comparación de ABI).

Si AbiAnalyzer encuentra un informe que no está vacío, establece la etiqueta Lint-1 y se bloquea el envío del cambio hasta que se resuelva; hasta que el conjunto de parches reciba una etiqueta Lint+1.

Actualizar la ABI del kernel

Si es inevitable modificar el ABI, debe aplicar los cambios de código, la representación de ABI y la lista de símbolos al ACK. Para que Lint elimine el -1 y no rompa la compatibilidad con GKI, siga estos pasos:

  1. Sube los cambios de código al ACK .

  2. Espere a recibir una revisión de código +2 para el conjunto de parches.

  3. Actualice la representación ABI de referencia .

  4. Combine los cambios de su código y el cambio de actualización de ABI.

Cargar cambios de código ABI al ACK

La actualización del ACK ABI depende del tipo de cambio que se realiza.

  • Si un cambio de ABI está relacionado con una característica que afecta las pruebas CTS o VTS, el cambio generalmente se puede seleccionar para ACK tal como está. Por ejemplo:

  • Si un cambio de ABI es para una característica que se puede compartir con el ACK, ese cambio se puede seleccionar para ACK tal como está. Por ejemplo, los siguientes cambios no son necesarios para la prueba CTS o VTS, pero se pueden compartir con ACK:

  • Si un cambio de ABI introduce una nueva característica que no necesita incluirse en el ACK, puede introducir los símbolos en el ACK usando un código auxiliar como se describe en la siguiente sección.

Utilice apéndices para ACK

Los stubs deben ser necesarios sólo para cambios del núcleo central que no benefician al ACK, como cambios de rendimiento y energía. La siguiente lista detalla ejemplos de resguardos y selecciones parciales en ACK para GKI.

  • Código auxiliar de función de aislamiento de núcleo ( aosp/1284493 ). La funcionalidad en ACK no es necesaria, pero los símbolos deben estar presentes en ACK para que sus módulos utilicen estos símbolos.

  • Símbolo de marcador de posición para el módulo de proveedor ( aosp/1288860 ).

  • Selección exclusiva de ABI de la función de seguimiento de eventos mm por proceso ( aosp/1288454 ). El parche original se seleccionó cuidadosamente para ACK y luego se recortó para incluir solo los cambios necesarios para resolver la diferencia ABI para task_struct y mm_event_count . Este parche también actualiza la enumeración mm_event_type para contener los miembros finales.

  • Selección parcial de cambios ABI de estructura térmica que requirieron algo más que simplemente agregar los nuevos campos ABI.

    • El parche aosp/1255544 resolvió las diferencias de ABI entre el kernel asociado y ACK.

    • El parche aosp/1291018 solucionó los problemas funcionales encontrados durante las pruebas de GKI del parche anterior. La solución incluyó la inicialización de la estructura de parámetros del sensor para registrar múltiples zonas térmicas en un solo sensor.

  • CONFIG_NL80211_TESTMODE ABI cambia ( aosp/1344321 ). Este parche agregó los cambios de estructura necesarios para ABI y aseguró que los campos adicionales no causaran diferencias funcionales, lo que permitió a los socios incluir CONFIG_NL80211_TESTMODE en sus núcleos de producción y aún mantener el cumplimiento de GKI.

Aplicar el KMI en tiempo de ejecución

Los kernels GKI usan las opciones de configuración TRIM_UNUSED_KSYMS=y y UNUSED_KSYMS_WHITELIST=<union of all symbol lists> , que limitan los símbolos exportados (como los símbolos exportados usando EXPORT_SYMBOL_GPL() ) a aquellos enumerados en una lista de símbolos. Todos los demás símbolos no se exportan y se deniega la carga de un módulo que requiera un símbolo no exportado. Esta restricción se aplica en el momento de la compilación y se marcan las entradas que faltan.

Para fines de desarrollo, puede usar una compilación del kernel GKI que no incluya el recorte de símbolos (lo que significa que se pueden usar todos los símbolos exportados habitualmente). Para localizar estas compilaciones, busque las compilaciones kernel_debug_aarch64 en ci.android.com .

Aplicar el KMI mediante el control de versiones del módulo

Los kernels de Generic Kernel Image (GKI) utilizan el control de versiones del módulo ( CONFIG_MODVERSIONS ) como una medida adicional para hacer cumplir el cumplimiento de KMI en tiempo de ejecución. El control de versiones del módulo puede causar fallas de coincidencia en la verificación de redundancia cíclica (CRC) en el momento de la carga del módulo si el KMI esperado de un módulo no coincide con el KMI vmlinux . Por ejemplo, el siguiente es un fallo típico que se produce en el momento de la carga del módulo debido a una discrepancia de CRC para el 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 del versionado de módulos

El control de versiones del módulo es útil por los siguientes motivos:

  • El control de versiones del módulo detecta cambios en la visibilidad de la estructura de datos. Si los módulos cambian estructuras de datos opacas, es decir, estructuras de datos que no forman parte del KMI, se romperán después de futuros cambios en la estructura.

    Como ejemplo, considere el campo fwnode en struct device . Este campo DEBE ser opaco para los módulos para que no puedan realizar cambios en los campos de device->fw_node ni hacer suposiciones sobre su tamaño.

    Sin embargo, si un módulo incluye <linux/fwnode.h> (directa o indirectamente), entonces el campo fwnode en el struct device ya no es opaco para él. Luego, el módulo puede realizar cambios en device->fwnode->dev o device->fwnode->ops . Este escenario es problemático por varias razones, que se exponen a continuación:

    • Puede romper las suposiciones que el código central del núcleo hace sobre sus estructuras de datos internas.

    • Si una futura actualización del kernel cambia la struct fwnode_handle (el tipo de datos de fwnode ), entonces el módulo ya no funciona con el nuevo kernel. Además, stgdiff no mostrará ninguna diferencia porque el módulo rompe el KMI al manipular directamente las estructuras de datos internas de maneras que no se pueden capturar simplemente inspeccionando la representación binaria.

  • Un módulo actual se considera incompatible con KMI cuando lo carga en una fecha posterior un nuevo kernel que es incompatible. El control de versiones del módulo agrega una verificación del tiempo de ejecución para evitar cargar accidentalmente un módulo que no sea compatible con KMI con el kernel. Esta verificación evita problemas de tiempo de ejecución difíciles de depurar y fallas del kernel que podrían resultar de una incompatibilidad no detectada en el KMI.

Habilitar el control de versiones del módulo evita todos estos problemas.

Verifique si hay discrepancias en CRC sin iniciar el dispositivo

stgdiff compara e informa discrepancias de CRC entre núcleos junto con otras diferencias de ABI.

Además, una compilación completa del kernel con CONFIG_MODVERSIONS habilitado genera un archivo Module.symvers como parte del proceso de compilación normal. Este archivo tiene una línea para cada símbolo exportado por el kernel ( vmlinux ) y los módulos. Cada línea consta del valor CRC, el nombre del símbolo, el espacio de nombres del símbolo, el vmlinux o el nombre del módulo que exporta el símbolo y el tipo de exportación (por ejemplo, EXPORT_SYMBOL versus EXPORT_SYMBOL_GPL ).

Puede comparar los archivos Module.symvers entre la compilación GKI y su compilación para verificar si hay diferencias de CRC en los símbolos exportados por vmlinux . Si hay una diferencia de valor CRC en cualquier símbolo exportado por vmlinux y ese símbolo es utilizado por uno de los módulos que carga en su dispositivo, el módulo no se carga.

Si no tiene todos los artefactos de compilación, pero sí tiene los archivos vmlinux del kernel GKI y su kernel, puede comparar los valores CRC para un símbolo específico ejecutando el siguiente comando en ambos kernels y comparando el resultado:

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

Por ejemplo, el siguiente comando verifica el valor CRC para el símbolo module_layout :

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Resolver discrepancias de CRC

Utilice los siguientes pasos para resolver una discrepancia de CRC al cargar un módulo:

  1. Compile el kernel GKI y el kernel de su dispositivo usando la opción --kbuild_symtypes como se muestra en el siguiente comando:

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

    Este comando genera un archivo .symtypes para cada archivo .o . Consulte KBUILD_SYMTYPES en Kleaf para obtener más detalles.

    Para Android 13 y versiones anteriores, cree el kernel GKI y el kernel de su dispositivo anteponiendo KBUILD_SYMTYPES=1 al comando que usa para compilar el kernel, como se muestra en el siguiente comando:

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

    Cuando se utiliza build_abi.sh, el indicador KBUILD_SYMTYPES=1 ya está establecido implícitamente.

  2. Busque el archivo .c en el que se exporta el símbolo con falta de coincidencia CRC, usando el siguiente comando:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. El archivo .c tiene un archivo .symtypes correspondiente en GKI y los artefactos de compilación del kernel de su dispositivo. Localice el archivo .c usando los siguientes comandos:

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

    Las siguientes son las características del archivo .c :

    • El formato del archivo .c es una línea (potencialmente muy larga) por símbolo.

    • [s|u|e|etc]# al inicio de la línea significa que el símbolo es del tipo de datos [struct|union|enum|etc] . Por ejemplo:

      t#bool typedef _Bool bool
      
    • Un prefijo # faltante al inicio de la línea indica que el símbolo es una función. Por ejemplo:

      find_module s#module * find_module ( const char * )
      
  4. Compare los dos archivos y solucione todas las diferencias.

Caso 1: Diferencias debido a la visibilidad del tipo de datos

Si un kernel mantiene un símbolo o tipo de datos opaco para los módulos y el otro kernel no, esa diferencia aparece entre los archivos .symtypes de los dos kernels. El archivo .symtypes de uno de los núcleos tiene UNKNOWN para un símbolo y el archivo .symtypes del otro núcleo tiene una vista ampliada del símbolo o tipo de datos.

Por ejemplo, agregar la siguiente línea al archivo include/linux/device.h en su kernel provoca discrepancias de CRC, una de las cuales es para module_layout() :

 #include <linux/fwnode.h>

La comparación de module.symtypes para ese símbolo expone las siguientes diferencias:

 $ 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 ] ; }
  ...

Si su kernel tiene un valor UNKNOWN y el kernel GKI tiene la vista ampliada del símbolo (muy poco probable), entonces combine el kernel común de Android más reciente en su kernel para que esté utilizando la base del kernel GKI más reciente.

En la mayoría de los casos, el kernel GKI tiene un valor de UNKNOWN , pero su kernel tiene los detalles internos del símbolo debido a los cambios realizados en su kernel. Esto se debe a que uno de los archivos de su kernel agregó un #include que no está presente en el kernel de GKI.

A menudo, la solución es tan simple como ocultar el nuevo #include de genksyms .

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

De lo contrario, para identificar el #include que causa la diferencia, siga estos pasos:

  1. Abra el archivo de encabezado que define el símbolo o tipo de datos que tiene esta diferencia. Por ejemplo, edite include/linux/fwnode.h para la struct fwnode_handle .

  2. Agregue el siguiente código en la parte superior del archivo de encabezado:

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. En el archivo .c del módulo que tiene una discrepancia de CRC, agregue lo siguiente como primera línea antes de cualquiera de las líneas #include .

    #define CRC_CATCH 1
    
  4. Compila tu módulo. El error de tiempo de compilación resultante muestra la cadena del archivo de encabezado #include que provocó esta discrepancia de CRC. Por ejemplo:

    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"
    

    Uno de los eslabones de esta cadena de #include se debe a un cambio realizado en su kernel, que falta en el kernel de GKI.

  5. Identifique el cambio, reviertalo en su kernel o cárguelo en ACK y combínelo .

Caso 2: Diferencias debido a cambios de tipo de datos

Si la discrepancia de CRC para un símbolo o tipo de datos no se debe a una diferencia en la visibilidad, entonces se debe a cambios reales (adiciones, eliminaciones o cambios) en el tipo de datos en sí.

Por ejemplo, realizar el siguiente cambio en su kernel provoca varias discrepancias en CRC, ya que muchos símbolos se ven afectados indirectamente por este tipo de cambio:

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);

Una discrepancia de CRC es para devm_of_platform_populate() .

Si compara los archivos .symtypes para ese símbolo, podría verse así:

 $ 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 el tipo modificado, siga estos pasos:

  1. Busque la definición del símbolo en el código fuente (normalmente en archivos .h ).

    • Para diferencias de símbolos simples entre su kernel y el kernel GKI, busque la confirmación ejecutando el siguiente comando:
    git blame
    
    • Para los símbolos eliminados (donde un símbolo se elimina en un árbol y también desea eliminarlo en el otro árbol), necesita encontrar el cambio que eliminó la línea. Utilice el siguiente comando en el árbol donde se eliminó la línea:
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. Revise la lista de confirmaciones devueltas para localizar el cambio o la eliminación. La primera confirmación es probablemente la que estás buscando. Si no es así, revise la lista hasta encontrar la confirmación.

  3. Después de identificar el cambio, revertirlo en su kernel o cargarlo en ACK y fusionarlo .