Partizione di ripristino personalizzata


9

Sto lavorando a un progetto in cui gli aggiornamenti a Raspberry PI avverranno su HTTP e Raspberry PI non sarà direttamente accessibile (non si possono semplicemente scambiare le carte).

Vorrei avere una configurazione della partizione in questo modo:

  • Partizione 1- / boot (contiene i kernel per entrambe le partizioni)
  • Partizione 2- / (partizione di ripristino)
  • Partizione 3- / (partizione primaria)

Quando un aggiornamento si interrompe e Raspberry PI entra in un ciclo di riavvio o si blocca all'avvio, vorrei che l'utente fosse in grado di premere un pulsante, che attiva una linea GPIO, che causerebbe l'avvio del caricatore di avvio nel partizione di ripristino anziché la partizione primaria.

La partizione di ripristino non verrà mai aggiornata, quindi sarebbe al sicuro.

Vedo un paio di opzioni:

  1. Avvia sempre nella partizione di ripristino, controlla GPIO, quindi avvia nella partizione primaria senza premere alcun pulsante
  2. GPIO viene controllato direttamente dal caricatore di avvio

Sto fondamentalmente cercando di fare qualcosa di simile a quello che fanno i router, dove se tieni premuto reset mentre si avvia, puoi TFTP su una nuova immagine o qualcosa del genere.

È possibile con Raspberry PI? Se è così, c'è qualche documentazione per fare questo genere di cose?

Modificare:

Ho trovato questa risposta a questa domanda correlata: è possibile eseguire il dual boot dalla scheda SD?

Un commento sulla domanda precedente mi ha portato qui: http://www.berryterminal.com/doku.php/berryboot . Sembra promettente, ma dovrò ricercarlo di più per vedere se riesco a ottenere una lettura GPIO da esso. Se qualcuno ha qualche esperienza con esso, sarei molto interessato.


Facci sapere come va avanti, sembra interessante :)
Jivings

1
Penso di aver trovato un modo per farlo scrivendo un semplice bootloader di 2a fase, quindi mi assicurerò di documentarlo qui se ci provo. Spero ancora in una soluzione semplice ...
beatgammit

1
Sfortunatamente no, ma ho ridotto significativamente la possibilità di corruzione usando un filesystem RO: /boot(RO), /(RO), /var(RW), /home(RW). Il problema iniziale era la corruzione del filesystem quando l'alimentazione veniva interrotta durante l'avvio. Mi piacerebbe comunque scrivere / trovare un bootloader di 2 ° stadio.
Beatgammit,

1
Potresti vedere cosa fa il bootloader NOOBS ( raspberrypi.org/archives/4100 ) per il Pi. Potrebbe effettivamente adattarsi ai tuoi scopi solo per usarlo, in quanto prevede partizioni di ripristino e installazione.
Fred

1
Sto suggerendo '' contro '' utilizzando un bootloader personalizzato, ma uso gli hack che vengono eseguiti dopo l'avvio del sistema. Sarà più facile da implementare e più sicuro per il debug. Un bootloader difettoso può friggere il tuo Pi.
Maxthon Chan,

Risposte:


5

Se l'errore può verificarsi in qualsiasi momento dopo l'avvio del sistema, è possibile utilizzare un timer watchdog e alcuni script di avvio.

Il principio di questo metodo è che ogni volta che il sistema si riavvia senza arrestarsi correttamente, passa alla partizione di ripristino.

È necessario scrivere uno script che viene eseguito ogni volta che il sistema si avvia e si spegne correttamente. Passare /boot/cmdline.txtalla partizione di ripristino all'avvio del sistema e ripristinarlo prima di spegnerlo correttamente.

Quindi impostare il timer del watchdog. È possibile utilizzare quello integrato nel chip BCM2835 o (se si utilizza una scheda di revisione 2) costruire il proprio utilizzando due pin GPIO, l'intestazione di ripristino P6 e un chip 555. Quando viene avviato il programma critico, avviare il timer del watchdog e calciare periodicamente il cane se il sistema funziona correttamente. Quando il sistema non funziona, il timer del watchdog verrà attivato e reimposta il processore, quindi lo invia alla partizione di ripristino. Ciò non richiede alcuna interazione da parte dell'utente e, se si utilizza il timer incorporato, nessun GPIO.

Utilizzando questo metodo, è anche possibile implementare un pulsante di ripristino che garantirà l'invio manuale del ripristino su una scheda Rev. 2 installando un pulsante nell'intestazione P6.


La tua prima risposta è un po 'più vicina a ciò che probabilmente farei, ma mi piace l'idea di usare i GPIO nello spazio utenti e un watchdog. Anche se probabilmente non userò nessuna delle idee all'ingrosso, mi hai dato alcune buone idee. Grazie!
Beatgammit,

1

Ho un modo per farlo senza hackerare il kernel, che prevede la protezione del sistema da un riavvio prematuro:

  1. Scarica l'immagine di aggiornamento, esegui il checksum ed espanderlo nello spazio scratch.
  2. Modificare /boot/cmdline.txt in modo che al successivo avvio del sistema utilizzi la partizione di ripristino come dispositivo di blocco root.
  3. Installa l'aggiornamento dallo spazio di memoria virtuale e verifica che funzioni.
  4. Se l'aggiornamento funziona, cambia /boot/cmdline.txt indietro.
  5. Se necessario, riavviare.

Un aggiornamento fallito provocherà l'avvio automatico del sistema nel ripristino. Non è necessario GPIO.


L'unico problema qui è (a seconda del sistema) un errore può essere rilevato ore dopo il completamento dell'aggiornamento, a quel punto l'utente non ha alcuna opzione per ripristinare la partizione di ripristino.

1
@DanNixon Sto pubblicando un'altra risposta per risolvere questo nuovo problema.
Maxthon Chan,

1

Inoltre, esiste una terza soluzione possibile, ma richiederà di analizzare initrdalcune versioni PC della distribuzione Linux per capire come funziona la syscall pivot_init(). Non sono sicuro che il kernel di Pi abbia questo syscall. In tal caso, questo metodo è possibile, non è richiesto alcun hack del kernel e utilizza un GPIO.

Per fare ciò, dovrai scrivere un initprogramma personalizzato nel sistema di produzione. controlla se GPIO è attivo. In tal caso, pivot_root()per il recupero. Quindi exec()l'originale in initmodo che il sistema continui ad avviarsi. È possibile, nel sistema di produzione, trovare un modo per mantenere questo GPIO-watch costruito initparallelamente (PID = 2) con l'originale init(PID = 1) e tenere d'occhio il GPIO e riavviare il ripristino se il pulsante è premuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.