Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Monitoreo de ABI del kernel de Android

Puede utilizar las herramientas de supervisión de la interfaz binaria (ABI) de la aplicación, disponibles en Android 11 y versiones posteriores, para estabilizar la ABI en el núcleo de los núcleos de Android. Las colectas de herramientas y lo compara representaciones ABI de binarios kernel existente ( vmlinux + módulos). Estas representaciones son las ABI .xml archivos y las listas de símbolos. La interfaz en la que la representación ofrece una vista se denomina Interfaces del módulo del núcleo (KMI). Puede utilizar las herramientas para rastrear y mitigar los cambios en el KMI.

El utillaje monitoreo ABI se desarrolla en AOSP y usos libabigail para generar y comparar las 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 en el kernel. Esta página también proporciona información para contribuir con cambios en los kernels de Android.

Este directorio contiene las herramientas específicas para el análisis ABI. Utilizarlo con los scripts de construcción proporcionados por build_abi.sh ).

Proceso

Analizar la ABI del kernel requiere varios pasos, la mayoría de los cuales se pueden automatizar:

  1. Adquirir la cadena de herramientas, scripts de construcción, y fuentes del núcleo a través repo .
  2. Proporcionar los requisitos previos (como el libabigail biblioteca y colección de herramientas).
  3. Construir el núcleo y su representación ABI .
  4. Analizar las diferencias entre la acumulación de ABI y una referencia .
  5. Modificar la representación ABI (si es necesario) .
  6. Trabaja con listas de símbolos .

Las siguientes instrucciones son para cualquier núcleo que se puede construir utilizando un conjunto de herramientas soportado (como la cadena de herramientas de pre-compilados Clang). repo manifests están disponibles para todas las ramas del núcleo común de Android y de varios núcleos de dispositivo específicos, se aseguran de que las herramientas correctas se utiliza cuando se genera una distribución del núcleo para su análisis.

Uso de las herramientas de monitoreo ABI

1. Adquiera la cadena de herramientas, cree scripts y fuentes del kernel a través del repositorio.

Puede adquirir la cadena de herramientas, scripts de construcción (estos scripts), y fuentes del núcleo con repo . Para obtener documentación detallada, consulte la información correspondiente para la construcción de núcleos Android .

Para ilustrar el proceso, los pasos siguientes se utilizan common-android12-5.10 , una rama del kernel de Android, que es el último núcleo GKI lanzado en el momento de escribir estas líneas. Para obtener esta rama a través repo , ejecute el siguiente:

repo init -u https://android.googlesource.com/kernel/manifest -b common-android12-5.10
repo sync

2. Proporcionar requisitos previos

Las herramientas ABI utilizan libabigail, una biblioteca y colección de herramientas, para analizar binarios. Un conjunto adecuado de binarios precompilados viene con el kernel-construcción-herramientas y se utiliza de forma automática con build_abi.sh .

Para utilizar las herramientas de nivel inferior (como dump_abi ), añadir las herramientas kernel-acumulación en el PATH .

3. Construya el kernel y su representación ABI

En este punto ya está listo para construir un kernel con la cadena de herramientas correctas y para extraer una representación de ABI sus binarios ( vmlinux + módulos).

Al igual que en el proceso de construcción del kernel Android habitual (usando build.sh ), este paso se necesita correr build_abi.sh .

BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh

Que construye el núcleo y extrae la representación ABI en el out_abi subdirectorio. En este caso out/android12-5.10/dist/abi.xml es un enlace simbólico a out_abi/android12-5.10/dist/abi-<id>.xml . < id> se calcula mediante la ejecución de git describe contra el árbol de fuentes del núcleo.

4. Analizar las diferencias ABI entre la construcción y una representación de referencia.

build_abi.sh análisis e informes cualquier diferencia ABI cuando se proporciona una referencia a través de la variable de entorno ABI_DEFINITION . ABI_DEFINITION debe apuntar a un archivo de referencia en relación con las fuentes del núcleo, y puede ser especificado en la línea de comandos o, más comúnmente, como un valor en build.config. A continuación se proporciona un ejemplo:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh

En el comando anterior, build.config.gki.aarch64 define el archivo de referencia (como ABI_DEFINITION=android/abi_gki_aarch64.xml ), y diff_abi llamadas abidiff para comparar la representación ABI recién generado contra el archivo de referencia. build_abi.sh imprime la ubicación del informe y emite un informe corto para cualquier rotura ABI. Si se detectan roturas, build_abi.sh termina y devuelve un código de salida distinto de cero.

5. Actualice la representación ABI (si es necesario)

Para actualizar la representación ABI, invoque build_abi.sh con el --update bandera. Se actualiza el correspondiente abi.xml archivo que se define por build.config . Para imprimir las diferencias ABI debido a la actualización, invoque el script con --print-report . Asegúrese de incluir el informe en el mensaje de confirmación cuando se actualiza el abi.xml archivo.

6. Trabajar con listas de símbolos

Parameterize build_abi.sh con KMI listas de símbolos a símbolos de filtro durante la extracción de ABI. Estos son archivos de texto sin formato que enumeran los símbolos del kernel ABI relevantes. Por ejemplo, un archivo de lista de símbolos con el siguiente contenido limita análisis ABI a los símbolos ELF con los nombres symbol1 y symbol2 :

[abi_symbol_list]
   symbol1
   symbol2

No se consideran cambios en otros símbolos ELF. Un archivo de lista de símbolos se puede especificar en el correspondiente build.config archivo de configuración con KMI_SYMBOL_LIST= como un archivo relativo al directorio de fuentes del núcleo ( $KERNEL_DIR ). Para proporcionar un nivel de organización, puede especificar los archivos de lista de símbolos adicionales utilizando ADDITIONAL_KMI_SYMBOL_LISTS= en el build.config archivo. Esto especifica más archivos de lista de símbolos, en relación con $KERNEL_DIR ; separe varios nombres de archivo por espacios en blanco.

Para crear una lista de símbolos inicial o actualizar una existente, debe utilizar el build_abi.sh script con el --update-symbol-list parámetro.

Cuando la secuencia de comandos se ejecuta con una configuración apropiada, se construye el núcleo y extrae los símbolos que se exportan desde vmlinux módulos y GKI y que son requeridos por cualquier otro módulo en el árbol.

Considere vmlinux exportación de los siguientes símbolos (normalmente se hace a través de la EXPORT_SYMBOL* macros):

  func1
  func2
  func3

También, se imaginan había dos módulos proveedores, modA.ko y modB.ko , que requieren los siguientes símbolos (en otras palabras, que la lista undefined entradas de símbolos en su tabla de símbolos):

 modA.ko:    func1 func2
 modB.ko:    func2

Desde el punto de vista de estabilidad ABI, func1 y func2 debe mantenerse estable, a medida que se utilizan por un módulo externo. Por el contrario, mientras que func3 se exporta, no se utiliza de forma activa (en otras palabras, no es necesario) por cualquier módulo. Por lo tanto, la lista de símbolos contiene func1 y func2 solamente.

Para crear o actualizar una lista de símbolos existentes, build_abi.sh debe ser la siguiente:

BUILD_CONFIG=path/to/build.config.device build/build_abi.sh --update-symbol-list

En este ejemplo, build.config.device debe incluir varias opciones de configuración:

  • vmlinux debe estar en el FILES lista.
  • KMI_SYMBOL_LIST debe ser conjunto y que apunta a la lista de símbolos KMI de actualización.
  • GKI_MODULES_LIST se debe establecer y apuntando a la lista de módulos GKI. Este camino es por lo general android/gki_aarch64_modules .

Trabajar con las herramientas ABI de nivel inferior

La mayoría de los usuarios sólo tendrán que utilizar build_abi.sh . En algunos casos, puede ser necesario trabajar directamente con las herramientas ABI de nivel inferior. Los dos comandos utilizados por build_abi.sh , dump_abi y diff_abi , están disponibles para extraer y comparar archivos ABI. Consulte las siguientes secciones para conocer sus usos.

Creación de representaciones ABI a partir de árboles del kernel

Proporcionado un árbol núcleo de Linux con una función vmlinux módulos y de almendra, la herramienta dump_abi crea una representación ABI ABI usando la herramienta seleccionada. Un ejemplo de invocación se ve así:

dump_abi --linux-tree path/to/out --out-file /path/to/abi.xml

El archivo abi.xml contiene una representación textual de la ABI combinado, ABI observable de vmlinux y los módulos del kernel en el directorio dado. Este archivo puede usarse para inspección manual, análisis adicional o como archivo de referencia para reforzar la estabilidad de ABI.

Comparación de representaciones ABI

Representaciones creadas por ABI dump_abi pueden compararse con diff_abi . Utilizar la misma herramienta-abi tanto para dump_abi y diff_abi . Un ejemplo de invocación se ve así:

diff_abi --baseline abi1.xml --new abi2.xml --report report.out

El informe generado enumera los cambios ABI detectados que afectan al KMI. Los archivos especificados como baseline y de new son representaciones ABI que fueron recogidos con dump_abi . diff_abi propaga el código de salida de la herramienta subyacente y por lo tanto devuelve un valor distinto de cero cuando los ABIs comparados son incompatibles.

Usar listas de símbolos de KMI

Para representaciones de filtrado que crea con dump_abi símbolos o filtrar en comparación con diff_abi , utilice el parámetro --kmi-symbol-list , que toma una ruta a un archivo KMI lista de símbolos:

dump_abi --linux-tree path/to/out --out-file /path/to/abi.xml --kmi-symbol-list /path/to/symbol_list_file

Comparación de los binarios del kernel con la KMI de referencia de GKI

Mientras trabaja en el cumplimiento GKI Kernel, es útil comparar periódicamente la construcción del kernel local para una referencia representación GKI KMI sin tener que usar build_abi.sh . La herramienta gki_check es una herramienta ligera para hacer exactamente eso. Dado un árbol de compilación del kernel de Linux local, una invocación de muestra para comparar la representación de los binarios locales, por ejemplo, es cómo comparar con la representación 5.4:

build/abi/gki_check --linux-tree path/to/out/ --kernel-version 5.4

gki_check utiliza nombres de los parámetros consistentes con dump_abi y diff_abi . Por lo tanto, --kmi-symbol-list path/to/kmi_symbol_list_file se puede utilizar para limitar que la comparación a los símbolos permitidos por pasar una lista de símbolos KMI.

Manejo de 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 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 */

Cuando se ejecuta build_abi.sh de nuevo con este parche aplicado, las salidas de herramientas con un código de error distinto de cero y reporta una diferencia ABI similar a esto:

 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:
  [...]

Arreglando una ABI rota 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 funciones agregadas o eliminadas, estructuras de datos modificadas o cambios en la ABI causados ​​por la adición de opciones de configuración que conducen a cualquiera de los mencionados anteriormente. Empiece por abordar los problemas encontrados por la herramienta.

Puede reproducir la prueba ABI localmente mediante la ejecución del siguiente comando con los mismos argumentos que se habría utilizado para el funcionamiento de build/build.sh :

Este es un comando de ejemplo para los núcleos GKI:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh

Actualización de la ABI del kernel

Si es necesario actualizar la representación del núcleo ABI, a continuación, debe actualizar la correspondiente abi.xml archivo en el árbol de fuentes del núcleo. La manera más conveniente de hacerlo es mediante el uso de build/build_abi.sh de este modo:

build/build_abi.sh --update --print-report

Utilizar los mismos argumentos que se habría utilizado para ejecutar build/build.sh . Esto actualiza la correcta abi.xml en el árbol de fuentes y las impresiones las diferencias detectadas. Como práctica, incluya el informe impreso (breve) en el mensaje de confirmación (al menos parcialmente).

Ramas del kernel de Android con ABI predefinida

Algunas ramas del kernel vienen con representaciones ABI predefinidas para Android como parte de su distribución de código fuente. Estas representaciones ABI están destinados para ser exactos, y para reflejar el resultado de build_abi.sh como si desea ejecutar por su cuenta. A medida que el ABI está fuertemente influenciado por las diversas opciones de configuración del kernel, estas .xml archivos por lo general pertenecen a una determinada configuración. Por ejemplo, el common-android12-5.10 rama contiene un abi_gki_aarch64.xml que se corresponde con el resultado de compilación cuando se utiliza el build.config.gki.aarch64 . En particular, build.config.gki.aarch64 también hace referencia a este archivo a través ABI_DEFINITION .

Tales representaciones ABI predefinidos se utilizan como una definición de línea de base cuando se compara con diff_abi . Por ejemplo, para validar un parche del núcleo con respecto a cualquier cambio en el ABI, crear la representación ABI con el parche aplicado y utilizar diff_abi al compararlo con el ABI esperado para ese árbol de fuentes o configuración particular. Si ABI_DEFINITION se establece, corriendo build_abi.sh en consecuencia va a hacer.

Hacer cumplir la KMI mediante el control de versiones del módulo

El uso GKI núcleos módulo de control de versiones ( CONFIG_MODVERSIONS ) para hacer cumplir KMI en tiempo de ejecución. Versiones de módulo causará fallos CRC desajuste en el módulo de carga a tiempo si el KMI esperado de un módulo no coincide con el vmlinux KMI. Por ejemplo, aquí es un fracaso típico que se produce en el módulo de carga de tiempo debido a una falta de coincidencia 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 control de versiones del módulo

El control de versiones del módulo es útil por muchas razones:

  1. Detecta cambios en la visibilidad de la estructura de datos. Si los módulos pueden cambiar las estructuras de datos opacas, como las estructuras de datos que no forman parte del KMI, los módulos se romperán después de futuros cambios en la estructura.
  2. Agrega una verificación de tiempo de ejecución para evitar cargar accidentalmente un módulo que no es compatible con KMI con el kernel. (Por ejemplo, cuando un módulo actual se carga en una fecha posterior por un nuevo kernel que es incompatible). Esto es preferible a tener problemas de tiempo de ejecución posteriores difíciles de depurar o fallas del kernel.
  3. abidiff tiene limitaciones en la identificación de diferencias ABI en ciertos casos enrevesados que CONFIG_MODVERSIONS puede coger.

Como ejemplo de (1), considere la fwnode campo en struct device . Ese campo deberá ser opaco a los módulos por lo que no pueden hacer cambios en los campos de device->fw_node o supuestos tome acerca de su tamaño.

Sin embargo, si un módulo incluye <linux/fwnode.h> (directa o indirectamente), entonces el fwnode campo en el struct device deja de ser opaco a la misma. Un módulo puede realizar cambios en device->fwnode->dev o device->fwnode->ops . Eso es problemático por varias razones:

  1. Puede romper las suposiciones que el código del núcleo del núcleo está haciendo sobre sus estructuras de datos internas.

  2. Si una futura actualización del kernel cambia el struct fwnode_handle (el tipo de datos de fwnode ), entonces el módulo no funcionará con el nuevo kernel. Por otra parte, abidiff no mostrará ninguna diferencia ya que el módulo está rompiendo el KMI manipulando directamente las estructuras de datos internas de manera que no se pueden capturar sólo por la inspección de la representación binaria.

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

Comprobación de discrepancias de CRC sin iniciar el dispositivo

Cualquier construcción del kernel con CONFIG_MODVERSIONS habilitado no generar un Module.symvers archivo como parte del proceso de construcción. El archivo tiene una línea para cada símbolo exportado por el vmlinux y los módulos. Cada línea consiste en el valor del CRC, el nombre de símbolo, símbolo de espacio de nombres, vmlinux o nombre del módulo que está exportando el símbolo, y el tipo de exportación (por ejemplo, EXPORT_SYMBOL vs EXPORT_SYMBOL_GPL ).

Puede comparar los Module.symvers archivos entre la acumulación GKI y su construcción para comprobar 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 es utilizado por uno de los módulos se cargan en el dispositivo, el módulo no se puede cargar.

Si usted no tiene todos los artefactos de construcción, pero sólo tienen los vmlinux archivos del kernel GKI y su núcleo, puede comparar los valores de CRC para un símbolo específico ejecutando el siguiente comando en tanto los granos, a continuación, comparar la salida:

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

Por ejemplo, para comprobar el valor de CRC para el module_layout símbolo,

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Corregir la falta de coincidencia de CRC

Si obtiene una discrepancia de CRC al cargar el módulo, aquí se explica cómo solucionarlo:

  1. GKI construir el núcleo y el núcleo del dispositivo, y añadir KBUILD_SYMTYPES=1 delante del comando que se utiliza para construir el núcleo. Tenga en cuenta, cuando se utiliza build_abi.sh, esto se establece implícitamente ya. Esto generará un .symtypes archivo para cada .o archivo. Por ejemplo:

    KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
    
  2. Encuentra la .c archivo en el que se exporta el símbolo con el CRC desajuste. Por ejemplo:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. Eso .c archivo tiene un correspondiente .symtypes archivo en el GKI y su dispositivo artefactos construcción del kernel.

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

    una. El formato de este archivo es una línea (potencialmente muy larga) por símbolo.

    B. [s|u|e|etc]# al comienzo 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 .

    C. A falta # prefijo en el inicio de la línea indica el símbolo es una función. Por ejemplo,
    find_module s#module * find_module ( const char * ) .

  4. Compare esos dos archivos y corrija todas las diferencias.

Caso 1: diferencias debidas a la visibilidad del tipo de datos

Si un núcleo mantiene un símbolo o tipo de datos opaco a los módulos del núcleo y el otro no lo hace, a continuación, se muestra como una diferencia entre los .symtypes archivos de los dos núcleos. El .symtypes archivo desde uno de los núcleos tiene UNKNOWN para un símbolo y el .symtypes archivo del otro núcleo tiene una vista ampliada del símbolo o tipo de datos.

Por ejemplo, suponga que añadir esta línea a include/linux/device.h en el núcleo:

 #include <linux/fwnode.h>

Eso hace que los desajustes de CRC, con uno de ellos para module_layout() . Si se comparan los module.symtypes para ese símbolo, que se ve 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 ] ; }
  ...

Si el núcleo tiene como UNKNOWN y el núcleo GKI tiene la vista expandida del símbolo (muy poco probable), y luego fusionar la última Android Común del núcleo dentro del núcleo de modo que usted está utilizando la última base de GKI núcleo.

Casi siempre, el GKI kernel tiene como UNKNOWN , pero su núcleo tiene los detalles internos del símbolo debido a los cambios realizados en su núcleo. Esto se debe a que uno de los archivos en su núcleo añadió un #include que no está presente en el núcleo GKI.

Para identificar el #include que hace 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, editar 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. Luego, en el módulo de .c archivo (el que tiene un desajuste CRC), añada lo siguiente como la primera línea antes que cualquiera de los #include líneas.

    #define CRC_CATCH 1
    
  4. Ahora compile su módulo. Usted obtendrá un error en tiempo de compilación que muestra la cadena de archivo de cabecera #include que llevó a esta falta de coincidencia 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"
    
  5. Uno de los eslabones de esta cadena de #include es debido a un cambio hecho en su núcleo, que falta en el núcleo GKI.

  6. Una vez que identifique el cambio, que revertirá en su núcleo o subirlo a ACK y conseguir que se fusionó .

Caso 2: diferencias debido a cambios en el 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í. Típicamente, abidiff capturas esto, pero si se pierde cualquier debido a las lagunas de detección conocidos, la MODVERSIONS mecanismo puede capturarlos.

Por ejemplo, suponga que realiza el siguiente cambio en su kernel:

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

Eso provocaría una gran cantidad de desajustes CRC (todos los símbolos son afectados indirectamente por este tipo de cambio) y uno de ellos sería para devm_of_platform_populate() .

Si se comparan los .symtypes archivos para ese símbolo, podría tener este aspecto:

 $ 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 cambiado, siga estos pasos:

  1. Encuentra la definición del símbolo en el código fuente (por lo general en .h archivos).
  2. Si hay una diferencia obvia entre el símbolo de su núcleo y el núcleo GKI, hacer una git blame para encontrar la confirmación.
  3. A veces, un símbolo se elimina en un árbol y desea eliminarlo en el otro árbol. Para encontrar el cambio que eliminó la línea, ejecute este comando en el árbol donde se eliminó la línea:

    una. git log -S "copy paste of deleted line/word" -- <file where it was deleted>

    B. Obtendrá una lista abreviada de confirmaciones. El primero es probablemente el que estás buscando. Si no es así, revise la lista hasta que encuentre la confirmación.

  4. Una vez que identifique el cambio, ya sea revertirá en su núcleo o subirlo a ACK y conseguir que se fusionó .