Raspberry PI 4 – Trasferire il sistema da SD Card a USB Drive

Come ho già detto nel mio precedente articolo, capita più spesso di quanto si vorrebbe che il drive SD nel quale abbiamo installato il nostro bel sistema Raspbian completo di mille funzioni personalizzate decida di morire senza alcun preavviso, e renda irrecuperabili tutti i dati contenuti. Ho già spiegato in questo articolo come eseguire il boot di Raspberry PI 4 da USB. Ora invece vediamo come trasferire l’intero sistema installato su SD direttamente nel nostro drive USB.

Premetto che non si tratta di un metodo strettamente legato a Raspberry, e che fondamentalmente è possibile applicare i concetti qui espressi con qualsiasi drive. In fondo è un sistema che esiste da anni, ma è talmente comodo che ancora oggi è difficile non ricorrervi in casi come questo.

Premessa

Partiamo col dire cosa è necessario per eseguire il trasferimento.

  • Un mac o un pc con installato linux
  • La SD Card di Raspberry con il sistema funzionante
  • Una pendrive USB o un drive USB SDD o HDD

Procedura

Supponiamo si usi un mac (ma non cambia granché se usiamo linux, in caso si deve solo vedere se qualche parametro dei comandi usati si esprime in modo differente). Se possibile consiglio di settare la scheda SD in modalità sola lettura spostando l’apposito cursore che di solito è presente nell’adattatore da microSD a SD, quindi inseriamo la scheda SD e il drive USB nel MAC.

In un MAC i due drive verranno attivati e subito montati nel filesystem, in linux invece no. Non ci serve siano montati, quindi procediamo tramite “Utility Disco” a disattivare (non espellere) entrambi i drive.

Scopriamo i nomi che hanno assunto:

sudo diskutil list

Mac OS

sudo fdisk -l

Linux

Il comando ci fornisce la lista dei drive e delle relative partizioni presenti. Naturalmente nominate in modo opportuno a seconda del sistema. Al momento però le partizioni non ci interessano, quindi recuperiamo solo i nomi dei drive e supponiamo che siano (badate che molto probabilmente non corrispondono a questi):

/dev/disk5
/dev/disk6

Mac OS

/dev/sda
/dev/sdb

Linux

E supponiamo che il primo sia il drive SD mentre il secondo quello USB. Ora dobbiamo copiare bit per bit il contenuto del drive SD verso quello USB e per farlo possiamo usare il mitico dd.

sudo dd bs=32m if=/dev/disk5 of=/dev/disk6; sync

Mac OS

sudo dd if=/dev/sda of=/dev/sdb bs=4M conv=fsync

Linux

Durante la copia non è possibile vedere lo stato della progressione e il tempo necessario potrebbe essere anche molto, a seconda della dimensione del drive sorgente. Esiste però un metodo per sapere a che punto è arrivata la copia e consiste nel lanciare una chiamata kill al processo dd.
Si deve aprire una nuova finestra terminale sulla macchina che sta eseguendo la copia e lanciare il comando:

sudo kill -INFO $(pgrep ^dd$)

Mac OS

sudo kill -USR1 $(pgrep ^dd)

Linux

Nella finestra terminale dove è in corso l’esecuzione di dd troveremo stampato lo stato attuale della copia che intanto proseguirà regolarmente.

A lavoro terminato avremo il nostro drive USB clone esatto della scheda SD. Stessi contenuti, stesse partizioni e stesse dimensioni… e questo potrebbe essere non desiderabile. Mi spiego. Il comando dd esegue come detto una copia 1 a 1 del drive sorgente, e siccome il drive di destinazione deve essere di dimensione pari o superiore al sorgente può succedere che dello spazio non venga allocato. Non è spazio sprecato, è semplicemente non allocato e potremmo utilizzarlo per metterci delle nuove partizioni da utilizzare poi nel sistema Raspbian. Ma potremmo anche volerlo usare per estendere la partizione di root del sistema e dare più spazio “nativo” alle nostre personali installazioni. Come si fa?

Ridimensionamento della partizione di root

La procedura consiste nel cancellare la partizione di root, ricrearla più grande ed eseguire il comando resize2fs per ridimensionare il filesystem. È chiaramente una procedura delicata e potrebbe portare alla perdita di tutti i dati della partizione, quindi normalmente sarebbe necessario un backup prima di procedere, ma supposto che il backup sia il drive SD stesso da cui abbiamo fatto la copia possiamo saltare questo importante passaggio.

Per portare a termine l’operazione qui però è necessario usare un pc linux perché le partizioni e il comando resize2fs devono lavorare su partizioni di tipo non noto a MAC OS. Possiamo anche usare Raspberry, basta reinstallare temporaneamente il drive SD avviarlo e successivamente collegare il drive USB. Supponiamo quindi di trovarci in questa seconda ipotesi.

Prima di tutto eseguiamo

sudo lsblk -p

e scopriamo il nome della partizione da ridimensionare. Supponiamo sia /dev/sda2

Poi facciamo un bel controllo per verificare che il filesystem non contenga errori e in caso correggiamoli

sudo e2fsck -f /dev/sda2

Terminato il controllo passiamo alla gestione della partizione

sudo fdisk /dev/sda

Premiamo “p” e prendiamo nota del settore Start della partizione 2, supponiamo sia 532480.
Cancelliamo la partizione premendo “d”, alla domanda rispondiamo con la partizione 2. Ora abbiamo una sola partizione.
Creiamo una nuova partizione con “n”, di tipo primario con “p”, numero 2, facendola partire dal settore 532480 (a meno che non sia già suggerito uguale) e terminare all’ultimo (quello suggerito va benissimo). Non cancelliamo la firma ext4 che dovrebbe già essere contenuta, quindi alla domanda “Partition #2 contains a ext4 signature. Do you want to remove the signature? [Y]es/[N]o:” rispondiamo N.

Fin’ora tutte le modifiche fatte sono solo in memoria, non sono state applicate al disco. Se vogliamo uscire senza apportare modifiche basta premere “q”, ma se siamo sicuri di aver fatto tutto salviamo con “w”.
Ora dobbiamo estendere il filesystem ma prima un altro controllo:

sudo e2fsck -f /dev/sda2

e se tutto va bene

sudo resize2fs /dev/sda2

Quando ha terminato verifichiamo le partizioni

sudo lsblk -p

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
/dev/sda 8:0 0 465.8G 0 disk
├─/dev/sda1 8:1 0 256M 0 part
└─/dev/sda2 8:2 0 465.5G 0 part
/dev/mmcblk0 179:0 0 29.7G 0 disk
├─/dev/mmcblk0p1 179:1 0 256M 0 part /boot
└─/dev/mmcblk0p2 179:2 0 29.5G 0 part /

Montiamo temporaneamente la partizione

sudo mount /dev/sda2 /mnt

e verifichiamo il contenuto. Tutto ok? Bene! Spegniamo il Raspberry con un bel

sudo shutdown now

Scolleghiamo la scheda SD e riavviamo con il drive USB collegato.

Fatto!