Experiencia en la construcción de ensamblados de Linux para actualizaciones de placa única con soporte

imagen

Introduccion


Por el momento, el mercado ofrece una amplia gama de pagadores individuales para todos los gustos a un precio asequible.

Como regla general, varios conjuntos de fabricantes están diseñados para evaluar la plataforma y son el punto de partida de un nuevo proyecto, por lo tanto, no siempre son adecuados para tareas específicas. En tareas donde se requiere una alta confiabilidad, el desarrollador se enfrenta a la pregunta de cómo finalizar el kit de distribución y luego no pagarlo con una revisión completa de la imagen y el sistema de actualización.

En Internet, casi no hay información sobre cómo debería ser el conjunto de lanzamiento y cómo implementar su actualización, por lo que el desarrollador se ve obligado a idear una "bicicleta" o utilizar sus propios desarrollos, que no siempre se prueban al 100%.

Dado que participo en el desarrollo de software para varios dispositivos Linux (mi cartera puede ser google por la palabra develinux) y también soy el autor del proyecto de 11 partes, regularmente tengo que ocuparme no solo de la construcción de ensamblajes, sino también del desarrollo de mecanismos de actualización a través de WEB o USB flash.

En este artículo quiero compartir mi experiencia y conocimiento en áreas relevantes.

Requisitos de montaje


En el proceso de desarrollo de ensamblajes y actualizaciones para varios dispositivos, identifiqué varios requisitos para mí:

  • el conjunto no debe dañarse cuando la alimentación se apaga repentinamente;
  • el ensamblaje debe cargarse rápidamente;
  • el gestor de arranque debería funcionar sin problemas;
  • El ensamblaje debe ser compatible con la actualización.

Trataré de explicar estos requisitos con más detalle a continuación, y luego describiré 3 enfoques en la división de imágenes en secciones y sus actualizaciones.

El conjunto no debe dañarse cuando la alimentación se apaga repentinamente.


¿Quién necesita un dispositivo que deja de funcionar después de un décimo reinicio? A nadie! Si toma distribuciones listas para usar (y hay muy pocas de ellas para incrustar), entonces, sin un archivo de la caja, todas son muy poco confiables a este respecto. Recordé muy bien el proyecto donde usé ubuntu bajo imx6, los sistemas de archivos en la tarjeta estaban dañados, a veces desde el décimo reinicio, a veces desde el cuadragésimo, dependía de las estrellas en el cielo. El proyecto salvó a FS aufs. El hecho es que ubuntu no está diseñado para solo lectura, y siempre debe escribir algo. Recuerdo una situación similar en otro proyecto donde yocto fue utilizado en una tarjeta SD. En general, tenga en cuenta que las tarjetas SD son el tipo de unidad más feo que se bloquea más rápido, mucho más confiable que emmc y nand. Si usa una tarjeta SD, es aconsejable escribirle lo menos posible durante la operación, los algoritmos de transferencia del sector de fondo son muy impredecibles, trabajé con docenas de diferentes tarjetas SD de marcas mundiales y no encontré una sola tarjeta que pudiera recomendar.
Pero las tarjetas SD tienen varias ventajas, son asequibles, económicas y convenientes para la depuración de software.

¿Por qué soy yo? Y, aquí está la cosa: el FS raíz debe ser de solo lectura, no debe haber ninguna entrada durante la operación. Probablemente pensarás: ¿cómo es eso? Millones de dispositivos Android siempre escriben algo y no fallan. Es cierto, pero todo esto se debe a que la mayoría de los dispositivos Android, en primer lugar, tienen una batería y, en segundo lugar, el FS raíz se enmarca como ramdisk, y la partición del sistema es de solo lectura.

Si el sistema debe ser confiable, todo tipo de cosas con la instalación de paquetes en la raíz FS puede estropear mucho. Recomiendo squashfs como sistema de archivos. Funciona rápido, no puede escribir nada, ahorra espacio debido a la compresión ...

Pero, ¿qué hay de guardar configuraciones, descargar archivos, etc. usted pregunta?
Pero para esto necesita crear particiones RW separadas. Si planea escribir en NAND, le recomiendo una opción probada: UBIFS. Si está en NOR, entonces jffs2. Si escribo en otra unidad, recomiendo ext4, btrfs, ReiserFS, no puedo señalar el mejor FS entre ellos, porque Hubo varios problemas con todos.

En este caso, siempre antes de montar particiones rw, asegúrese de verificar las particiones en busca de errores utilizando utilidades similares a fsck.

El ensamblaje debe cargarse rápidamente


Las velocidades de descarga del dispositivo afectan la usabilidad general. En algunas tareas, el tiempo de carga no es más de 30 segundos, en algunas, se permiten 5 minutos. Para mí, trabajé hasta 1 minuto, cuanto menos mejor. Espere la descarga durante más de un minuto durante demasiado tiempo, puede parecer que el dispositivo se ha colgado, por lo que si puede reducir el tiempo, entonces es mejor usarlo.

El gestor de arranque debería funcionar sin problemas


El cargador es lo que el ensamblaje no comenzará sin. Recientemente, a menudo observo cómo los fabricantes de placas simples facilitan el desarrollo al cargar una demostración para una tarjeta SD con una descripción de cómo registrar un gestor de arranque o una imagen terminada con un gestor de arranque, que simplemente se completa con el comando dd. ¿Pero qué pasa si la tarjeta SD se congela? Lo mismo no es raro. Personalmente, en mi práctica, las tarjetas a menudo se caían. Así es como trabaja por una tarifa durante varias horas, escribe software, bam y eso es todo ... los errores en el núcleo comienzan a aparecer, la tarjeta se cayó. Pero, ¿qué pasa si este es un dispositivo que debería funcionar en los campos sin reiniciar? Y, por cierto, reiniciar, incluido watchdog, no siempre revive una tarjeta colgada, la tarjeta no tiene una señal de reinicio, esto no es emmc, por supuesto, esta es más una pregunta para el circuito de la placa, si la placa tiene un reinicio del poder de la tarjeta, esto se guardará, pero esto no está en todas partes. En algunos tableros, solo distorsionar el poder o la tarjeta ayuda. Según mi experiencia, no recomiendo almacenar el cargador de arranque en la unidad con el conjunto principal si la grabación se realiza en la unidad durante la operación. Si el sistema no escribe nada en la unidad con el gestor de arranque, y esto rara vez ocurre, entonces, por favor. En mi experiencia, en modo de solo lectura, el sistema de archivos se deformaba solo debido a errores de hardware, pero no a errores de software.

El gestor de arranque debe almacenarse en un lugar seguro, en una unidad confiable, por ejemplo, en un chip NOR o EEPROM separado. A continuación se muestra un ejemplo de un módulo basado en el chip imx6ull, con SPI NOR para almacenar el gestor de arranque.

imagen

La compilación debe ser compatible con la actualización


Sin una actualización, en ninguna parte ... Participé en muchos proyectos y nunca obtuve el software perfecto para la entrega del trabajo. Siempre se detecta un error o se requiere una mejora funcional. Debe comprender que mientras las personas escriben software, cometerán errores, mientras que las personas usan el dispositivo, querrán un poco más. En el 90% de los casos, la falta de un sistema de actualización bien pensado puede llevar a un dolor de cabeza para el fabricante y al colapso de todo el proyecto. Por ejemplo, se ha desarrollado un sistema de videovigilancia para el transporte, el sistema se ha instalado en toda Rusia, y resulta que los vendedores subestimaron el mercado y no proporcionaron transmisión, y además, se encontraron varios errores en el firmware, además el consumidor comienza a mirar en la dirección de los competidores, porque han simplemente hay algo que no está en el dispositivo comprado ... Sí, sí, en un extraño jardín las fresas son más sabrosas y el clima es mejor (psicología).
¿Qué hacer en tal situación? Si la actualización es compatible, entonces hay muchas soluciones, los errores se pueden corregir, se puede mejorar la transmisión y la funcionalidad se puede personalizar para el consumidor, darle instrucciones al firmware del consumidor y eso es todo. Pero si no es compatible, el fabricante tendrá grandes aventuras con viajes de negocios de ingenieros de servicio hasta el reemplazo de dispositivos.

El sistema de actualización en el dispositivo debe ser pensado hasta el más mínimo detalle y probado al 100%. Un error en esta parte convertirá el hierro en ladrillo, por lo que no debe haber tolerancias ni excepciones.

El proceso de actualización debe ser resistente a la desconexión de la alimentación, y en ningún caso debe estropear el dispositivo.

Una descripción general de los enfoques de particionamiento para futuras actualizaciones


De los muchos enfoques, puedo recomendar 3 tipos que implementé personalmente. Estos no son todos los enfoques; su alcance está más allá del alcance de este artículo. Los 3 tipos tienen fallas y están lejos de ser ideales, pero, como me parece, están cerca del medio dorado del sentido común.

Enfoque n. ° 1


imagen

La forma más fácil y económica:
Se coloca una imagen en una unidad, por ejemplo, una tarjeta SD, que se actualiza desde u-boot en la unidad integrada del dispositivo, por ejemplo, NAND flash.
En u-boot, debe preparar scripts para esto.
De las ventajas: este es el tipo de actualización más fácil, cuyo desarrollo llevará un máximo de 1 día.
Las desventajas de este enfoque son la falta de visualización del proceso y las capacidades muy limitadas del gestor de arranque, es decir. sin lógica complicada con herramientas estándar, a menos que, por supuesto, se te ocurra tu propio comando u-boot (pero este es otro tipo de actualización, C es una gran fuerza). Este método no está diseñado para actualizaciones a través de WEB; es problemático controlar la integridad de la imagen del firmware; en algunos casos, el tamaño del ensamblaje no debe exceder el tamaño de la RAM.
Además, en algunas tareas se requiere guardar la configuración durante la actualización, y esto, con este enfoque, no es fácil de implementar.

Enfoque n. ° 2


imagen


El método más confiable y protegido de los considerados, pero el más difícil. Recomiendo este método para ser utilizado en desarrollos especialmente responsables, como Protege tanto de imágenes rotas como de daños físicos en la unidad principal, ya que el circuito usa una adicional.

El enfoque utiliza una compilación mínima (tamaño de disco RAM de 8-16 MB) y la principal. Ramdisk es un archivo comprimido, por lo que una compilación de 16 MB será físicamente varias veces más pequeña.
El objetivo de un ensamblaje mínimo es evaluar el ensamblaje principal y cargarlo.
Ramdisk está alojado con el kernel y las secuencias de comandos de u-boot en una imagen FIT.

¿Por qué la imagen FIT y qué da? La imagen FIT es un formato compatible con u-boot. Asegura la integridad de todos los componentes (kernel, dts, ramdisk, scripts). El desempaquetado de la imagen FIT se lleva a cabo en u-boot, y si la suma de comprobación no converge, u-boot se negará a cargarla. Esto es conveniente, es decir no es necesario que se encargue del control de integridad usted mismo, no necesita escribir varios archivos por separado o inventar sus propias imágenes, todo se hace mediante imagen FIT. Por lo general, una imagen FIT ocupa entre 7 y 20 MB, debe escribirse en una unidad independiente altamente confiable, por ejemplo, en qspi ni flash. El ensamblaje principal se puede almacenar en una memoria más barata y poco confiable, por ejemplo, flash NAND. Dado que el trabajo principal tendrá lugar en el ensamblaje principal, es precisamente lo que primero se dañará. En este caso, una unidad separada con rootfs mínimos vendrá al rescate.

Proceso de arranque

u-boot descarga un script que intenta usar las actualizaciones de FIT (FIT2), y luego el firmware de fábrica de FIT (FIT1).

Si FIT2 no está presente o se viola su integridad, la prueba de ajuste fallará y u-boot cargará el primer FIT (FIT1). Si hay actualizaciones FIT (FIT2), y no está roto, se carga su disco de memoria ram que verifica las actualizaciones de rootfs (Rootfs2).

Si Rootfs2 está roto, los scripts eliminarán las actualizaciones de FIT (FIT2), luego de reiniciar la imagen de fábrica que consiste en FIT (FIT1) y se descargará Rootfs1.

Proceso de actualización

La imagen de actualización contiene FIT, rootfs y diversa información de ensamblaje, incluidas las sumas de verificación de todos sus componentes. La información de ensamblaje se utiliza durante la actualización para monitorear la integridad y la compatibilidad.

Actualizar el progreso en pasos:

  • comprobar la compatibilidad de la imagen con hardware y software,
  • comprobando la integridad de la imagen en el archivo de actualización,
  • copiando Rootfs2 del archivo de actualización a una sección preparada previamente,
  • comprobando la integridad de la imagen copiada en la sección,
  • copia FIT2 a la sección apropiada,
  • reiniciar

Si el proceso falla, la ausencia o daño de FIT2 no arruinará el sistema, ya que u-boot simplemente se negará a usarlo y cargará la imagen de fábrica. Por lo tanto, durante la actualización, no se verifica la integridad de FIT2.

Después de la actualización, el nuevo ensamblado se colocará en la unidad principal en forma de FIT2 y Rootfs2.

Este método es resistente a daños mecánicos en el variador y errores FS.

En caso de mal funcionamiento crítico, se iniciará la imagen de fábrica, donde funcionará el software de recuperación, que, por ejemplo, puede verificar NAND, descargar el firmware de la red utilizando el protocolo SSH y luego anotarlo.

Solo di un ejemplo de recuperación, hay muchas opciones. En este enfoque, el proceso de recuperación es impulsado por Linux completo, que puede hacer todo ... y no el gestor de arranque como en la primera versión.

Enfoque no 3


imagen


Este tipo de actualización se utiliza en casi todos los proyectos de 11 partes, ya que ha funcionado muy bien.

La actualización es adecuada para cualquier tamaño de ensamblaje, para cualquier tipo de unidades. A diferencia del tipo anterior, aquí SPI NOR se usa solo para u-boot, por lo tanto, tiene un tamaño más pequeño y un costo menor, 1 MB es suficiente.

Este tipo de actualización no requiere una versión separada de ramdisk, lo que significa que se ahorra tiempo de programación para su desarrollo y soporte en el futuro.

El ejemplo usa una unidad de tarjeta SD, pero también puede ser NAND usando UBIFS, no hay diferencia. En este enfoque, no hay verificación de Rootfs RO antes de cargar, si el ensamblaje está dañado, el sistema no sabrá que estaba dañado y lo cargará en un círculo. Aquí se supone que los datos en la sección RO no se pueden cambiar de ninguna manera, este enfoque elimina el mal funcionamiento físico de la unidad. Si la unidad no está físicamente sana, entonces el dispositivo debe llevarse a un centro de servicio, no se proporciona autocuración. Este es el precio que tiene que pagar por aumentar la velocidad de desarrollo, el soporte más barato y la base elemental más barata, pero está justificado. ¿Por qué asegurarse contra algo que casi nunca sucede?

La lógica para descargar y actualizar es la misma que en el enfoque anterior.

En el caso de la carga, u-boot primero descarga las actualizaciones FIT (FIT2), si no está allí o si se viola la integridad, u-boot carga el primer FIT (FIT1), el ensamblaje que se cosió en la fábrica, y así sucesivamente hasta que se actualice el sistema. Cuando se actualiza el sistema, aparecerán FIT2 y Rootfs2. En este caso, cuando el dispositivo se inicia, la actualización FIT (FIT2) comienza primero. En los scripts de u-boot que se almacenan en cada FIT, se debe escribir qué rootfs montar.

Partición compartida RW


En los gráficos, hay un bloque de partición compartido en todas partes, este es un grupo de secciones para escribir. Cualquier entrada se hace solo allí. La partición compartida se muestra como una partición para mayor claridad. De hecho, hay 3 de ellos: dos pequeños para configuraciones que trabajan en el espejo y uno grande para todo lo demás. Además, le recomiendo que mantenga algunas de las configuraciones al actualizar, lo cual es conveniente, por ejemplo, si configura la red y actualiza, no necesitará reconfigurar la configuración de la red.

Para resumir


El artículo analiza tres tipos de ensamblajes con soporte para actualizaciones, todos revisados ​​personalmente por mí, puede usarlos de manera segura en proyectos.

Por el momento, uso solo los dos últimos, ya que son los más adecuados para los requisitos. Para mayor claridad, puede ver ejemplos de dispositivos en los que se utilizan estos tipos de actualizaciones (detalles en la cartera de 11 partes):

  • Repetidor RS485 a través de 4G / WiFi / LAN,
  • Tablero de control de controlador de pantalla industrial 4K V-By-One,
  • sistema integrado de control climático del hangar,
  • Controlador de video con pantalla industrial 2DisplayPort-LVDS,
  • sistema de control de línea
  • Puerta de enlace VPN.

Si mi artículo es útil e interesante, estoy listo para compartir aún más mi experiencia y soluciones técnicas probadas en el campo de Linux incorporado en este sitio.

Gracias a todos.
Gorchakov Ilya
telegrama: develinux

Source: https://habr.com/ru/post/470519/


All Articles