Partición de recuperación personalizada

9

Estoy trabajando en un proyecto donde las actualizaciones de Raspberry PI se realizarán a través de HTTP, y no se podrá acceder directamente a Raspberry PI (no solo se pueden intercambiar tarjetas).

Me gustaría tener una configuración de partición así:

  • Partición 1- / boot (contiene núcleos para ambas particiones)
  • Partición 2- / (partición de recuperación)
  • Partición 3- / (partición primaria)

Cuando una actualización falla y el Raspberry PI entra en un ciclo de reinicio, o se cuelga en el arranque, me gustaría que el usuario pueda presionar un botón, que activa una línea GPIO, lo que provocaría que el cargador de arranque se inicie en el partición de recuperación en lugar de la partición primaria.

La partición de recuperación nunca se actualizaría, por lo que esto sería seguro.

Veo un par de opciones:

  1. Siempre inicie en la partición de recuperación, verifique GPIO, luego inicie en la partición primaria sin presionar ningún botón
  2. GPIO es verificado por el gestor de arranque directamente

Básicamente, estoy tratando de hacer algo similar a lo que hacen los enrutadores, donde si mantiene presionado el reinicio mientras se inicia, puede TFTP sobre una nueva imagen o algo así.

¿Es esto posible con el Raspberry PI? Si es así, ¿hay alguna documentación para hacer este tipo de cosas?

Editar:

Encontré esta respuesta a esta pregunta relacionada: ¿Es posible realizar un arranque dual desde la tarjeta SD?

Un comentario sobre la pregunta anterior me llevó aquí: http://www.berryterminal.com/doku.php/berryboot . Esto parece prometedor, pero tendré que investigarlo más para ver si puedo obtener una lectura GPIO de él. Si alguien tiene alguna experiencia con él, estaría muy interesado.

beatgammit
fuente
Háganos saber cómo
sigue
1
Creo que encontré una manera de lograr esto escribiendo un simple gestor de arranque de la segunda etapa, así que me aseguraré de documentarlo aquí si me pongo a ello. Sin embargo, todavía espero una solución simple ...
beatgammit
1
Desafortunadamente no, pero reduje significativamente la posibilidad de corrupción usando un sistema de archivos RO: /boot(RO), /(RO), /var(RW), /home(RW). El problema inicial era la corrupción del sistema de archivos cuando se corta la energía durante el arranque. Sin embargo, todavía me gustaría escribir / encontrar un gestor de arranque de segunda etapa.
beatgammit
1
Podrías ver lo que hace el gestor de arranque NOOBS ( raspberrypi.org/archives/4100 ) para el Pi. En realidad, podría adaptarse a sus propósitos solo para usarlo, ya que proporciona particiones de recuperación e instalación.
Fred
1
Estoy sugiriendo '' en contra '' usando un gestor de arranque personalizado, pero use hacks que se ejecuten después de que se inicie el sistema. Será más fácil de implementar y más seguro depurar. Un gestor de arranque defectuoso puede freír tu Pi.
Maxthon Chan

Respuestas:

5

Si el error puede ocurrir en cualquier momento después de que se inició el sistema, puede usar un temporizador de vigilancia y alguna secuencia de comandos de arranque.

El principio de este método es que cada vez que el sistema se reinicia sin apagarse correctamente, va a la partición de recuperación.

Debe escribir un script que se ejecute cada vez que el sistema se inicie y se apague correctamente. Cambie /boot/cmdline.txta la partición de recuperación cuando se inicie el sistema y vuelva a cambiar antes de apagarse correctamente.

Luego configure el temporizador de vigilancia. Puede usar el integrado en el chip BCM2835 o (si usa una placa de revisión 2) construir el suyo usando dos pines GPIO, el encabezado de reinicio P6 y un chip 555. Cuando se inicia el programa crítico, inicie el temporizador de vigilancia y patee al perro periódicamente si el sistema funciona correctamente. Cuando el sistema falla, el temporizador de vigilancia se activará y reiniciará el procesador, lo enviará a la partición de recuperación. Esto tampoco requiere interacción del usuario y si se usa el temporizador incorporado, no GPIO.

Con este método, también puede implementar un botón de reinicio que garantizará enviar el sistema a recuperación manualmente en una placa Rev. 2 instalando un botón en el encabezado P6.

Maxthon Chan
fuente
Su primera respuesta está un poco más cerca de lo que probablemente haría, pero me gusta la idea de usar GPIO en el espacio de usuario y un perro guardián. Si bien probablemente no usaré ninguna de las ideas al por mayor, me has dado algunas buenas ideas. ¡Gracias!
beatgammit
1

Tengo una forma de hacerlo sin hackear el kernel, que implica proteger el sistema de un reinicio prematuro:

  1. Descargue la imagen de actualización, sume la suma de verificación y amplíela al espacio de memoria virtual.
  2. Cambie /boot/cmdline.txt para que la próxima vez que el sistema arranque use la partición de recuperación como dispositivo de bloqueo raíz.
  3. Instale la actualización desde el espacio temporal y verifique que esté funcionando.
  4. Si la actualización está funcionando, cambie /boot/cmdline.txt nuevamente.
  5. Si es necesario, reinicie.

Una actualización fallida hará que el sistema se inicie automáticamente en la recuperación. No se necesita GPIO.

Maxthon Chan
fuente
El único problema aquí es (dependiendo del sistema) un error puede ser detectado horas después de que se complete la actualización, momento en el cual el usuario no tiene la opción de volver a la partición de recuperación.
1
@DanNixon Estoy publicando otra respuesta para resolver este nuevo problema.
Maxthon Chan
1

Además, hay una tercera solución posible, pero requerirá que diseccione initrdalguna versión para PC de la distribución de Linux para descubrir cómo funciona la llamada al sistema pivot_init(). No estoy seguro de si el núcleo de Pi tiene esta llamada al sistema. Si lo hace, este método es posible, tampoco se requiere piratear el kernel, y utiliza un GPIO.

Para hacer eso, necesitará escribir un initprograma personalizado en el sistema de producción. compruebe si el GPIO está encendido. Si es así, pivot_root()a la recuperación. Luego exec()el original initpara que el sistema continúe arrancando. Puede, en el sistema de producción, encontrar una manera de mantener este GPIO construido en initejecución junto con el original init(PID = 1) y vigilar el GPIO y reiniciar para recuperarlo si Se presiona el botón.

Maxthon Chan
fuente