Cómo actualizar su kernel de Android a la última versión estable de Linux

Hemos cubierto guías sobre kernels de Android, tales como "Cómo construir un kernel personalizado" y "Best Kernels personalizados para Android", pero hoy le mostraremos cómo actualizar su kernel contra la última versión estable de Linux.

Tenga en cuenta que esto es algo avanzado : si nunca antes ha compilado un kernel, debe seguir la guía "Cómo construir un kernel personalizado" vinculada anteriormente, y esta guía incluirá la selección de cerezas y la fusión de los compromisos de la última versión de Linux- kernel estable con su kernel de Android antes de compilarlo.

La actualización de su kernel de Android a la última versión estable de Linux tiene muchos beneficios positivos, como estar actualizado con los últimos compromisos de seguridad y correcciones de errores: explicaremos algunos de los pros y los contras más adelante en esta guía.

¿Qué es el kernel estable de Linux?

Linux estable como su nombre lo indica es el brazo estable del kernel de Linux. El otro brazo se conoce como "línea principal", que es la rama maestra . Todo el desarrollo del kernel de Linux ocurre en la línea principal, y generalmente sigue este proceso:

  1. Linus Torvalds tomará un par de parches de sus mantenedores durante dos semanas.
  2. Después de estas dos semanas, lanza un kernel rc1 (por ejemplo, 4.14-rc1).
  3. Para cada semana durante las próximas 6-8 semanas, lanzará otro kernel RC (por ejemplo, 4.14-rc2, 4.14-rc3, etc.), que SOLO contiene correcciones de errores y regresión.
  4. Una vez que se considere estable, se lanzará como un tarball para descargar en la organización (por ejemplo, 4.14).

¿Qué son los núcleos LTS?

Cada año, Greg elegirá un núcleo y lo mantendrá durante dos años (LTS) o seis años (LTS extendido). Estos están diseñados para tener productos que necesitan estabilidad (como teléfonos Android u otros dispositivos IOT). El proceso es exactamente el mismo que el anterior, solo ocurre durante más tiempo. Actualmente hay seis núcleos LTS (que siempre se pueden ver en la página de lanzamientos de kernel.org):

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

¿Cuáles son los beneficios de actualizar mi kernel de Android a Linux Stable?

Cuando se revelan / arreglan vulnerabilidades importantes, los núcleos estables son los primeros en obtenerlas. Por lo tanto, su kernel de Android será mucho más seguro contra ataques, fallas de seguridad y solo errores en general.

La versión estable de Linux incluye correcciones para muchos controladores que mi dispositivo Android no usa, ¿no es esto innecesario?

Sí y no, dependiendo de cómo se defina "en su mayoría". El kernel de Linux puede incluir una gran cantidad de código que no se usa en el sistema Android, ¡pero eso no garantiza que no habrá conflictos de esos archivos al fusionar nuevas versiones! Comprenda que prácticamente nadie construye cada parte del núcleo, ni siquiera las distribuciones de Linux más comunes como Ubuntu o Mint. Esto no significa que no deba tomar estas correcciones porque hay correcciones para los controladores que sí ejecuta. Tome arm / arm64 y ext4, por ejemplo, que son la arquitectura y el sistema de archivos de Android más comunes, respectivamente. En 4.4, desde 4.4.78 (versión de la última etiqueta Oreo CAF) a 4.4.121 (última etiqueta ascendente), estos son los siguientes números para las confirmaciones de esos sistemas:

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

La parte que consume más tiempo es la presentación inicial; una vez que esté completamente actualizado, no lleva tiempo fusionarse en una nueva versión, que generalmente no contiene más de 100 confirmaciones. Sin embargo, los beneficios que esto trae (más estabilidad y mejor seguridad para sus usuarios) deberían necesitar este proceso.

Cómo combinar el kernel estable de Linux en un kernel de Android

Primero debe averiguar qué versión de kernel está ejecutando su dispositivo Android.

Por trivial que parezca, es necesario saber dónde debe comenzar. Ejecute el siguiente comando en su árbol de kernel:

 hacer kernelversion 

Le devolverá la versión en la que se encuentra. Los primeros dos números se usarán para determinar la rama que necesita (por ejemplo, linux-4.4.y para cualquier kernel 4.4) y el último número se usará para determinar qué versión necesita comenzar con la fusión (por ejemplo, si está en 4.4 .21, fusionará 4.4.22 a continuación).

Obtenga la última fuente de kernel de kernel.org

kernel.org alberga la última fuente de kernel en el repositorio estable de Linux. Al final de esa página, habrá tres enlaces de búsqueda. En mi experiencia, el espejo de Google tiende a ser el más rápido, pero sus resultados pueden variar. Ejecute los siguientes comandos:

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

Decide si quieres fusionar todo el kernel o elegir los commits

A continuación, deberá elegir si desea fusionar las confirmaciones o la selección de cereza. Aquí están los pros y los contras de cada uno y cuándo puede querer hacerlos.

NOTA: Si la fuente de su núcleo tiene la forma de un tarball, lo más probable es que necesite elegir, de lo contrario obtendrá miles de conflictos de archivos porque git está poblando el historial basado exclusivamente en el flujo ascendente, no lo que tiene el OEM o CAF cambiado Simplemente salte al paso 4.

Cosecha de la cereza:

Pros:

  • Es más fácil resolver conflictos ya que sabe exactamente qué conflicto está causando un problema.
  • Es más fácil volver a redactar, ya que cada confirmación es independiente.
  • Más fácil de dividir si tiene problemas

Contras:

  • Lleva más tiempo ya que cada confirmación debe seleccionarse individualmente.
  • Un poco más difícil de saber si commit es desde arriba a primera vista

Unir

Pros :

  • Es más rápido ya que no tiene que esperar a que se fusionen todos los parches limpios.
  • Es más fácil ver cuándo un commit es ascendente, ya que usted no será el confirmador, sino el mantenedor ascendente.

Contras:

  • Resolver conflictos puede ser un poco más difícil, ya que tendrá que buscar qué confirmación está causando el conflicto utilizando git log / git blame, no se lo informará directamente.
  • Rebasar es difícil ya que no se puede volver a armar una fusión, se ofrecerá elegir todo el compromiso individualmente. Sin embargo, no deberías hacer un rebase a menudo, sino usar git revert y git merge cuando sea posible.

Recomendaría hacer una selección de cereza para resolver los conflictos de problemas inicialmente, hacer una fusión, luego revertir los problemas confirmados luego para que la actualización sea más fácil (ya que la fusión es más rápida después de estar actualizado).

Agregue los commits a su fuente, una versión a la vez

La parte más importante de este proceso es la versión de una versión a la vez. PUEDE haber un parche problemático en su serie aguas arriba, que podría causar un problema al arrancar o interrumpir algo como el sonido o la carga (explicado en la sección de consejos y trucos). Hacer cambios de versión incrementales es importante por esta razón, es más fácil encontrar un problema en 50 confirmaciones que más de 2000 confirmaciones para algunas versiones. Solo recomendaría hacer una fusión completa una vez que conozca todas las confirmaciones de problemas y conflictos.

Cosecha de la cereza

Formato:

 git cherry-pick .. 

Ejemplo:

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

Unir

Formato:

 git merge 

Ejemplo:

git merge v3.10.74

Recomiendo realizar un seguimiento de los conflictos en las confirmaciones de fusión eliminando los # marcadores.

Cómo resolver conflictos

No podemos dar una guía paso a paso para resolver cada conflicto, ya que implica un buen conocimiento del lenguaje C, pero aquí hay algunos consejos.

Si se está fusionando, descubra qué commit está causando el conflicto. Puedes hacer esto de dos maneras:

  1. git log -pv $ (make kernelversion) .. para obtener los cambios entre su versión actual y la más reciente desde upstream. El indicador -p le dará los cambios realizados por cada confirmación para que pueda ver.
  2. Ejecute git blame en el archivo para obtener los hashes de cada confirmación en el área. Luego puede ejecutar git show –format = fuller para ver si el committer era de mainline / stable, Google o CodeAurora.
  • Averigua si ya tienes el commit. Algunos proveedores como Google o CAF intentarán buscar errores críticos, como la solución Dirty COW, y sus backports podrían entrar en conflicto con los de upstream. Puede ejecutar git log –grep = ”” y ver si devuelve algo. Si lo hace, puede omitir la confirmación (si selecciona cherry usando git reset –hard && git cherry-pick –continue) o ignore los conflictos (elimine <<<<< >>>>>).
  • Averigüe si ha habido un backport que está estropeando la resolución. A Google y CAF les gusta respaldar ciertos parches que no serían estables. Stable a menudo necesitará adaptar la resolución del compromiso de la línea principal a la ausencia de ciertos parches que Google opta por respaldar. Puede ver la confirmación de la línea principal ejecutando git show (el hash de la línea principal estará disponible en el mensaje de confirmación de la confirmación estable). Si hay un backport que lo está estropeando, puede descartar los cambios o puede usar la versión de la línea principal (que es lo que generalmente necesitará hacer).
  • Lea lo que intenta hacer el commit y vea si el problema ya está solucionado. A veces, CAF puede corregir un error independiente del flujo ascendente, lo que significa que puede sobrescribir su corrección para el flujo ascendente o descartarlo, como se indicó anteriormente.

De lo contrario, puede ser el resultado de una adición de CAF / Google / OEM, en cuyo caso solo necesita barajar algunas cosas.

Aquí hay un espejo del repositorio kernel.org linux-stable en GitHub, que puede ser más fácil para buscar listas de confirmación y diferencias para la resolución de conflictos. Recomiendo ir primero a la vista de lista de confirmación y localizar la confirmación del problema para ver la diferencia original y compararla con la suya.

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

También puede hacerlo a través de la línea de comando:

 git log .. git show 

Resolver resoluciones tiene que ver con el contexto. Lo que SIEMPRE debe hacer es asegurarse de que su diferencia final coincida con la de la cadena superior ejecutando los siguientes comandos en dos ventanas separadas:

 git diff HEAD git diff v $ (make kernelversion) .. $ (git tag --sort = -taggerdate -lv $ (make kernelversion | cut -d. -f 1, 2) * | head -n1) 

Habilitar rerere

Git tiene una característica llamada rerere (significa Reuse Recorded Resolution), lo que significa que cuando detecta un conflicto, registrará cómo lo resolvió para que pueda reutilizarlo más tarde. Esto es especialmente útil para los rebasers crónicos con fusión y selección de cerezas, ya que solo necesitará ejecutar git add. && git: continúe al rehacer la actualización anterior, ya que el conflicto se resolverá de la forma en que lo resolvió anteriormente.

Se puede habilitar ejecutando el siguiente comando en el repositorio del kernel:

 git config rerere.enabled true 

Cómo git bisect cuando se encuentra con un compilador o error de tiempo de ejecución

Dado que agregará una cantidad considerable de confirmaciones, es muy posible que introduzca un compilador o un error de tiempo de ejecución. ¡En lugar de simplemente rendirse, puede usar la herramienta bisecta incorporada de git para descubrir la causa raíz del problema! Idealmente, estará compilando y actualizando cada versión del núcleo a medida que la agregue, por lo que la división en biseles tomará menos tiempo si es necesario, pero puede dividir 5000 confirmaciones sin ningún problema.

Lo que hará git bisect es tomar un rango de confirmaciones, desde donde el problema está presente hasta donde no estaba presente, y luego comenzar a reducir a la mitad el rango de confirmación, permitiéndole construir y probar y hacerle saber si es bueno o no . Continuará esto hasta que escupe el compromiso que causa su problema. En ese punto, puede arreglarlo o revertirlo.

  1. Comience a bisecar: git bisect start
  2. Etiquete la revisión actual como mala: git bisect bad
  3. Etiquetar una revisión como buena: git bisect good
  4. Construir con la nueva revisión
  5. Según el resultado (si el problema está presente o no), dígale a git: git bisect good O git bisect bad
  6. ¡Enjuague y repita los pasos 4-5 hasta que se encuentre la confirmación del problema!
  7. Revertir o corregir el problema de confirmación.

NOTA: Las fusiones necesitarán ejecutar temporalmente git rebase -i para aplicar todos los parches a su rama para una bisección adecuada, ya que la bisección con las fusiones en su lugar a menudo se verificará en los compromisos ascendentes, lo que significa que no tiene ninguno de los compromisos específicos de Android. Puedo profundizar en esto a pedido, pero confía en mí, es necesario. Una vez que haya identificado el compromiso del problema, puede revertirlo o volverlo a fusionar.

NO aplaste las actualizaciones aguas arriba

Muchos desarrolladores nuevos están tentados a hacer esto, ya que es "más limpio" y "más fácil" de administrar. Esto es terrible por algunas razones:

  • Se pierde la autoría. Es injusto para otros desarrolladores que se les quite su crédito por su trabajo.
  • Bisecar es imposible. Si aplastas una serie de commits y algo es un problema en esa serie, es imposible saber qué commit causó un problema en un squash.
  • Las futuras selecciones de cerezas son más difíciles. Si necesita hacer un rebase con una serie aplastada, es difícil / imposible saber de dónde surge un conflicto.

Suscríbase a la lista de correo del kernel de Linux para recibir actualizaciones oportunas

Para recibir notificaciones cada vez que haya una actualización ascendente, suscríbase a la lista de anuncios de kernel de linux. Esto le permitirá recibir un correo electrónico cada vez que se lance un nuevo kernel para que pueda actualizar y enviar lo más rápido posible.

Artículos De Interés