Copia l'installazione esistente di Raspbian su una scheda SD più piccola


25

È possibile copiare un'installazione Raspbian esistente e configurata su una scheda SD più piccola?

Quando ho installato Raspbian per la prima volta avevo solo una scheda da 32 GB a portata di mano, ovviamente più grande del necessario.


Il sistema funzionerà meglio e la scheda durerà più a lungo con più spazio libero nella partizione primaria, quindi non ridurla troppo - mantienila almeno il doppio del tuo utilizzo (ad esempio, se il tuo sistema è 2-3 GB usa un Scheda da 8 GB e amplia la partizione per riempire tutto lo spazio disponibile). Nota che se non hai sviluppato la partizione per iniziare, non sarà di 32 GB, quindi potresti non doverla restringere.
riccioli d'oro

Grazie per averlo sottolineato, ma il mio Raspberry sta attualmente utilizzando solo 1,8 GB perché è un'installazione davvero di base. Quindi immagino che 4 GB dovrebbero essere sufficienti.
mwld,

Immagino di averlo ingrandito quando ho installato Debian Wheezy per la prima volta. Ora l'ho ridotto a 2,5 GB, ma ancora senza successo. Vedi i miei commenti qui sotto.
mwld


1
Se una delle risposte seguenti soddisfa la tua domanda, controlla la risposta.
Wes Mode,

Risposte:


12

In questa risposta, dimostrerò cosa fare passo dopo passo affinché le persone comprendano la logica alla base della soluzione e siano in grado di applicare i passaggi agli altri problemi.

Ma in primo luogo, si dovrebbe affermare che è un problema generico (non specifico per raspi) migrare i filesystem da una scheda SD a una scheda SD più piccola (ma abbastanza grande per i dati).

Requisiti

Un laptop con un lettore di schede micro SD e Linux (preferisco Ubuntu) in esecuzione su di esso.

Abbreviazioni

PIBOX      : Raspberry Pi which is used
SD_CARD_A  : 8GB micro SD card which is used on PIBOX and on which Raspbian-lite (the OS) is installed
SD_CARD_B  : 2GB micro SD card which will be used on PIBOX and on which Raspbian-lite (the OS) will be installed

Partizioni di SD_CARD_A

Mentre PIBOX è in esecuzione, elenchiamo le partizioni (qui non vengono visualizzate partizioni di sistema non necessarie).

root@pibox:~# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      7.3G  1.1G  5.9G  16% /
/dev/mmcblk0p1 vfat       63M   21M   43M  33% /boot

Ci sono 2 partizioni su SD_CARD_A come /e /boot. Anche 2 GB non vengono utilizzati in totale.

Backup SD_CARD_A

Dopo aver spento e arrestato PIBOX, estraiamo SD_CARD_A dalla scheda PIBOX e lo inseriamo nel lettore di schede del nostro laptop.

Le partizioni di SD_CARD_A vengono automaticamente montate sul nostro sistema come /dev/sdc1e /dev/sdc2.

root@mylaptop:~# df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/sdb2                     ext4       22G   13G  7.9G  63% /
/dev/sdb1                     vfat      197M  2.6M  195M   2% /boot/efi
/dev/sda8                     ext4       66G   11G   52G  17% /home
/dev/sdc1                     vfat       63M   21M   43M  33% /media/some_user_name/boot
/dev/sdc2                     ext4      7.3G  1.1G  5.9G  16% /media/some_user_name/some_uuid_serial

Smontiamo quelle partizioni dal nostro sistema per operare con successo su di esse.

root@mylaptop:~# umount /dev/sdc1
root@mylaptop:~# umount /dev/sdc2

Mostriamo le informazioni sul dispositivo di SD_CARD_A in dettaglio per le conferme nei passaggi successivi.

root@mylaptop:~# fdisk -l /dev/sdc
Disk /dev/sdc: 7969 MB, 7969177600 bytes
246 heads, 62 sectors/track, 1020 cylinders, total 15564800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x2019f6d8

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/sdc2          137216    15564799     7713792   83  Linux

Sopra puoi vedere che SD_CARD_A ha una capacità di 8 GB.

Cloniamo SD_CARD_A nel file pibox.img.

root@mylaptop:~# dd bs=4MB if=/dev/sdc of=pibox.img
1992+1 records in
1992+1 records out
7969177600 bytes (8.0 GB) copied, 416.582 s, 19.1 MB/s

Controlla la dimensione dei byte copiati, è uguale al valore ottenuto dal fdisk -l /dev/sdccomando.

Modulo loopback Linux

Linux ha un modulo chiamato loopback che ci fornisce la gestione di un file come dispositivo a blocchi.

Carichiamo il modulo loopback.

root@mylaptop:~# modprobe loop

Troviamo un percorso di dispositivo di loopback inutilizzato.

root@mylaptop:~# losetup -f /dev/loop0

Ora creiamo un dispositivo di loopback per il file pibox.img.

root@mylaptop:~# losetup /dev/loop0 pibox.img

Attiviamo il kernel per le modifiche alle partizioni.

root@mylaptop:~# partprobe /dev/loop0

Confermiamo se le operazioni precedenti hanno esito positivo.

root@mylaptop:~# losetup /dev/loop0
/dev/loop0: [0806]:69 (/root/pibox.img)

Visualizziamo le informazioni del dispositivo di loopback in dettaglio per confrontarle con SD_CARD_A.

root@mylaptop:~# fdisk -l /dev/loop0
Disk /dev/loop0: 7969 MB, 7969177600 bytes
255 heads, 63 sectors/track, 968 cylinders, total 15564800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x2019f6d8

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/loop0p2          137216    15564799     7713792   83  Linux

Sopra puoi vedere che le dimensioni del dispositivo di loopback (= 7969177600 byte) e le partizioni sono uguali a quelle di SD_CARD_A.

Matematica di base

D'ora in poi, ci concentreremo sulla partizione /dev/loop0p2. Chiamiamolo THE_PARTITION .

La dimensione del blocco è di 512 byte (come stampato sulla riga che inizia con Unità = settori .....)

THE_PARTITION inizia dal blocco 137216 e termina al blocco 15564799, il che significa che ha le dimensioni di 15427584 blocks(= 15564799 - 137216 + 1).

Pertanto, la dimensione di THE_PARTITION in byte è 7898923008 bytes(= 512 * 15427584).

Per adattarsi a THE_PARTITION in SD_CARD_B, vogliamo che abbia una nuova dimensione 3710940 blocks o in altre parole 1900001280 bytes(= 512 * 3710940).

Pertanto, il nuovo numero di blocco finale viene 3848155calcolato da start block number(= 137216) + size in blocks(= 3710940) - 1.

File system vs. partizione

Ci sono 2 operazioni che non devono essere confuse l'una con l'altra.

  • Ridimensionamento del filesystem. Ridurremo il file system su THE_PARTITION impostandone le dimensioni su 3710940 blocks.
  • Ridimensionamento della partizione. Ridurremo THE_PARTITION impostando il numero del blocco finale su 3848155.

Riduzione del filesystem

Prima di ridurre il file system, dovrebbe essere contrassegnato come pulito da e2fsck.

root@mylaptop:~# e2fsck -f /dev/loop0p2
e2fsck 1.42.9 (4-Feb-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/loop0p2: 41175/475776 files (0.2% non-contiguous), 309183/1928448 blocks

Riduciamo il file system con resize2fs.

root@mylaptop:~# resize2fs /dev/loop0p2 3710940s
resize2fs 1.42.9 (4-Feb-2014)
Resizing the filesystem on /dev/loop0p2 to 463867 (4k) blocks.
The filesystem on /dev/loop0p2 is now 463867 blocks long.

Riduzione della partizione

Impariamo con che numero THE_PARTITION è parted.

root@mylaptop:~# parted /dev/loop0
GNU Parted 2.3
Using /dev/loop0
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Model: Loopback device (loop)
Disk /dev/loop0: 7969MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      4194kB  70.3MB  66.1MB  primary  fat16        lba
 2      70.3MB  7969MB  7899MB  primary  ext4

(parted) quit

Riduciamo THE_PARTITION con parted.

root@mylaptop:~# parted /dev/loop0 unit s resizepart 2 3848155
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes  

Abbiamo finito con il dispositivo di loopback. Lo stacciamo.

root@mylaptop:~# losetup -d /dev/loop0

Troncamento del file immagine

Verifichiamo la nuova tabella delle partizioni.

root@mylaptop:~# fdisk -l pibox.img 

Disk pibox.img: 7969 MB, 7969177600 bytes
255 heads, 63 sectors/track, 968 cylinders, total 15564800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x2019f6d8

    Device Boot      Start         End      Blocks   Id  System
pibox.img1            8192      137215       64512    c  W95 FAT32 (LBA)
pibox.img2          137216     3848155     1855470   83  Linux

Nell'output si vede chiaramente che il numero del blocco finale di THE_PARTITION è ridotto from 15564799 to 3848155.

L'ultimo blocco che usiamo è 3848155. La numerazione dei blocchi inizia da 0. Quindi, abbiamo 3848155 + 1 blocchi in totale e la nuova dimensione del file pibox.img dovrebbe essere 1970255872 bytes (= (3848155 + 1) * 512).

Tronciamo il file pibox.img.

root@mylaptop:~# truncate --size=1970255872 pibox.img

Verifichiamo le nuove dimensioni del file pibox.img.

root@mylaptop:~# ls -l pibox.img 
-rw-r--r-- 1 root root 1970255872 Oct 13 21:53 pibox.img

Creazione di SD_CARD_B

Abbiamo inserito SD_CARD_B nel lettore di schede del nostro laptop. Le partizioni di SD_CARD_B vengono automaticamente montate sul nostro sistema come /dev/sdc1e /dev/sdc2.

root@mylaptop:~# df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/sdb2                     ext4       22G   13G  7.9G  63% /
/dev/sdb1                     vfat      197M  2.6M  195M   2% /boot/efi
/dev/sda8                     ext4       66G   11G   52G  17% /home
/dev/sdc1                     vfat       63M   21M   43M  33% /media/some_user_name/boot
/dev/sdc2                     ext4      1.8G  1.6G   59M  97% /media/some_user_name/some_uuid_serial

Sopra puoi vedere che SD_CARD_B ha una capacità di 2 GB.

Smontiamo quelle partizioni dal nostro sistema per operare con successo su SD_CARD_B.

root@mylaptop:~# umount /dev/sdc1
root@mylaptop:~# umount /dev/sdc2

Cloniamo il file pibox.img in SD_CARD_B.

root@mylaptop:~# dd bs=4MB if=pibox.img of=/dev/sdc
492+1 records in
492+1 records out
1970255872 bytes (2.0 GB) copied, 646.967 s, 3.0 MB/s

Controlla la dimensione dei byte copiati, è uguale al valore ottenuto dal ls -l pibox.imgcomando.

Avvio di PIBOX

Dopo aver rimosso SD_CARD_B dal nostro laptop e averlo inserito nella scheda PIBOX, avviamo il sistema e accediamo alla console PIBOX.

Elenchiamo le partizioni (alcune altre partizioni di sistema non necessarie non vengono visualizzate qui).

root@pibox:~# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      1.8G  1.1G  601M  64% /
/dev/mmcblk0p1 vfat       63M   21M   43M  33% /boot

Buona Penso che alcune delle tue cose con l'impostazione del loopback possano essere lunghe e inutili, potresti voler dare un'occhiata. Qualcosa di molto simile da una domanda molto simile: raspberrypi.stackexchange.com/a/29952/5538
goldilocks

@goldilocks, non testato ma penso sia necessario utilizzare il loopback. Per quanto ne so che parted non può funzionare direttamente sul file immagine, ha bisogno di un'interfaccia del dispositivo per le sue operazioni.
vaha,

Sì, ma penso che scoprirai che non devi preoccuparti losetupo addirittura -o loop=whatever. Come per l'altro post ho appena usato mount -o offset=123 /imagefilepath /mntpointe l'uso del loopback è implicito. Presumo che questo sia generalmente vero su Linux ora - prova a vedere. Potresti quindi ridurlo fino a dire semplicemente che le partizioni sono montate tramite un "dispositivo di loopback" virtuale.
Riccioli d'oro

5

Quando hai usato dd if=/dev/sdx of=/path/to/image bs=1M, si /dev/sdxriferisce all'intero "disco", quindi l'immagine sarebbe sempre la dimensione dell'intera scheda.

Invece, dovresti usare dd if=/dev/sdxn ...dov'è nil numero di partizione.

Probabilmente dovrai farlo due volte: una volta per la /bootpartizione e una volta per la /partizione.

Quindi avresti bisogno di creare partizioni sulla nuova scheda che siano grandi almeno quanto quelle due originali, per riportare il contenuto.


3

Usa qualcosa come parted (editor di partizioni) per ridurre la partizione primaria a una dimensione più piccola e quindi usa uno strumento come Clonezilla per copiare dalla partizione ora più piccola alla tua nuova scheda. Tuttavia, probabilmente dovrai farlo su un altro computer.


Purtroppo questo non ha funzionato. Ho ridotto la partizione a 2,5 GB con GParted. Ma quando ho provato a creare un'immagine da essa su una chiavetta USB è diventata molto più grande (4,3 GB - ma penso che volesse copiare tutti i 32 GB e mi sono fermato a 4,3 GB a causa della limitazione della dimensione del file FAT).
mwld,

2
Ho usato il comando dd if=/dev/sdx of=/path/to/image bs=1Mda questo thread: raspberrypi.stackexchange.com/questions/311/…
mwld

Hai idee su come posso semplicemente copiare la partizione primaria con 2,5 GB in un'immagine e comunque creare una scheda SD con Raspbian avviabile da essa?
mwld,

Scusa per la risposta in ritardo. Ho iniziato con una scheda SD da 4 GB, ho creato un'immagine e poi ho scritto quell'immagine su schede da 8 GB e più grandi. Non ho ancora avuto bisogno di usare una partizione più grande per tutto ciò su cui ho lavorato. Non conosco uno strumento che ti consentirà di creare un'immagine di una singola partizione su una scheda SD.
Jerry Gagnon,

3
  1. Crea un'immagine della scheda utilizzando uno dei metodi già menzionati: come posso eseguire il backup di Raspberry Pi?

  2. Usa lo script su http://sirlagz.net/2013/03/10/10/script-automatic-rpi-image-downsizer/ per ridimensionare l'immagine

  3. Ripristina l'immagine ridimensionata su una nuova scheda più piccola


Mi sono imbattuto in questa pagina mentre sto cercando di raggiungere lo stesso obiettivo per avere il backup della mia immagine raspbian, tuttavia non voglio tutta la scheda SOLO dati rilevanti sulla scheda. Come suggerito sopra, stavo cercando uno script qui sirlagz.net/2013/03/10/10/script-automatic-rpi-image-downsizer ma non sono riuscito a trovarne uno. qualcuno potrebbe aggiornare su questo link se è disponibile da qualche parte?
Shallyverma,

Posso ancora accedere al link e il post stesso è uno script. Copia lo script in un file e chiamalo script.sh, Rendi eseguibile il file usando chmoded eseguilo.
Mihir,

1

Sto usando rsyncper copiare filesystem da un disco all'altro da un po 'di tempo, senza problemi. Il vantaggio di usare rsync è che sta copiando il contenuto del filesystem, piuttosto che fare una copia a livello di blocco del dispositivo; di conseguenza, in realtà non importa le dimensioni dell'unità di destinazione e di origine, a condizione che l'unità di destinazione disponga di spazio sufficiente per contenere i dati.

Quindi ecco come lo farei:

  1. Crea una nuova installazione di raspbian sulla nuova scheda SD più piccola desiderata.
  2. Avviare nella nuova installazione ed espandere il filesystem per riempire l'intero disco. Chiudi il pi.
  3. Ora monta le nuove e vecchie schede e usale rsync -avx oldFilesystem newFilesystemper copiare / sovrascrivere il filesystem sulla nuova scheda con il filesystem della vecchia scheda.
  4. Infine, avvia il tuo nuovo sistema ed eseguilo rpi-updateper assicurarti che il tuo firmware sia coerente e aggiornato.

Dopodiché, sulla tua nuova scheda dovrebbe essere installato un sistema Raspbian perfettamente funzionante.


Quindi, per questo metodo (passaggio 3), ho bisogno di 2 lettori di schede SD?
Victor Van Hee,

Due lettori di schede SD o un dispositivo intermedio. Puoi risincronizzare il vecchio filesystem in una cartella sul tuo disco rigido, quindi risincronizzare quella cartella sulla seconda scheda SD, se non vuoi prendere un lettore.
sdenton4,

1

Ho creato uno script di shell per il backup e il ripristino di tutti i dati su una scheda SD. Elimina prima alcuni dati (corrispondenti al mio progetto) e riduce la partizione alla dimensione minima in modo che l'immagine sia grande quanto i dati sulla scheda SD. Come aggiunta, lo script crea un file * .zip dell'immagine. Dopo aver ripristinato l'immagine creata su un'altra scheda SD, la partizione verrà ingrandita alla dimensione massima. Lo script utilizza i comandi menzionati nelle altre risposte. Dato che questo è il mio script di pugno con queste dimensioni, mi ci sono volute ore per crearlo e non è un jet perfetto. Soprattutto non so come gestire i valori di ritorno di resize2fs e fdisk, quindi l'utente deve digitare i valori di cui ho bisogno. Ci sono idee per risolverlo? Spero che questa sceneggiatura aiuti qualcun altro. Sentiti libero di modificarlo e migliorarlo.

"Usage:
    <skriptname> -b <path>                  create backup of SC Card (dev/mmcblk0) to file <path>/JJJJ-MM-DD_HHMM.img
    <skriptname> -r <path>/FILENAME.img     restore an exitsting image (<path>/FILENAME.img) to the SD Card (dev/mmcblk0) 
    <skriptname> -r <path>/FILENAME.zip     unzip and restore an exitsting image (<path>/FILENAME.zip) to the SD Card (dev/mmcblk0)
    <skriptname> -h                         show this hlep

Ecco qui:

#!/bin/bash 

# check if the user is root
if (( $EUID != 0 )); then
  echo "This script requires root privileges please run as root"
  exit
fi


while getopts ":b:r:h" opt; do
  case $opt in
    b)
      mode="backup"
      OUTPATH=$OPTARG
      ;;
    r)
      mode="restore"
      DIRFILENAME=$OPTARG
      ;;
    h)
      mode="help"
      ;;
    \?)
      echo "Invalid option: -$OPTARG. Use -h for help" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument. Use -h for help" >&2
      exit 1
      ;;
  esac
done
# no option
if [ $OPTIND == 1 ]
then
  echo "$(basename "$0") needs an option! Use -h for help"
  exit 1
fi


myMount(){
  # create mountpoint if not existing
  if [ ! -d /tmp/sd2/ ] ; then
    mkdir /tmp/sd2
  fi

  # mount partition
  mount -v -t ext4 /dev/mmcblk0p2 /tmp/sd2
  err=$?
  if [ $err != 0 ]; then
    echo "mount failed error: $err"
    exit 1
  fi
}

myUmount(){
  cd /home/ # otherwise umount will fail
  # fuser -vm /tmp/sd2/

  # umount partition
  umount -v /tmp/sd2
  err=$?
  if [ $err != 0 ]; then
    echo "umount failed error: $err"
    exit 1
  fi
}

myEnlarge(){
  echo "enlarge partition..."
  # enlarge partition is not posible with fdisk -> delete and recreate it
  (
  echo d # delete partition
  echo 2 # patition number
  echo n # add a new partition
  echo p # primary partition
  echo 2 # partition number
  echo   # first sector (accept default: varies)
  echo   # last sector (accept default: varies)
  echo w # write changes
  ) | fdisk /dev/mmcblk0

  echo "\n check filesystem... "
  e2fsck -f -v -C 0 /dev/mmcblk0p2

  # enlarge filesystem to maxsize
  resize2fs -p /dev/mmcblk0p2
}

case "$mode" in
"help")
  echo "Usage:
    $(basename "$0") -b <path>                  create backup of SC Card (dev/mmcblk0) to file <path>/JJJJ-MM-DD_HHMM.img
    $(basename "$0") -r <path>/FILENAME.img     restore an exitsting image (<path>/FILENAME.img) to the SD Card (dev/mmcblk0) 
    $(basename "$0") -r <path>/FILENAME.zip     unzip and restore an exitsting image (<path>/FILENAME.zip) to the SD Card (dev/mmcblk0)
    $(basename "$0") -h                         show this hlep
--------------------------------
Adrian Zeitler, Germany 2017"
  ;;
"backup")  ####################################### backup ####################################### 
  echo "an image of the SD Card (/dev/mmcblk0) whitch is as smal as possible will be created to $OUTPATH."
  # ------------------  delete some data --------------------

  echo "Do you want to delete tempfiles? [y/n]" 
  read delfiles

  if [ "$delfiles" = "y" ]
    then
      echo "Delete tempfiles..."

      myMount

      # remove some data
      cd /tmp/sd2/home/alarm/
      rm -v -f hagelbeere.db
      rm -v -f HAILcam.log
      rm -v -f HAILcam.log.1
      rm -v -f test.jpg

      myUmount

    elif [ "$delfiles" = "n" ]
      then
    echo "I don't delete anything."
    else
    echo "Sorry, I didn't understand."
    exit 1
  fi


  # --------------------------------------------------------------
  # shrink partition 2 to minimum size

  echo "check file system... "
  e2fsck -f -v -C 0 /dev/mmcblk0p2
  err=$?
  if [ $err != 0 ]; then
    echo "file system check failed, error: $err"
    exit 1
  fi

  echo "shrink filesystem of partition 2 to minimum size..."
  resize2fs -p -M /dev/mmcblk0p2
  err=$?
  if [ $err != 0 ]; then
    echo "resize2fs failed, error: $err"
    exit 1
  fi
  # --> Das Dateisystem auf /dev/mmcblk0p2 ist nun 692365 Blöcke groß.

  echo "Please tell me the new filesystem size displayed above:"
  read size
  # from resize2fs blocksize, fdisk wants sector: sector = block * 8
  size=$(( $size*8 ))

  # shrink partition is not posible with fdisk -> delete and recreate it
  (
  echo d # delete partition
  echo 2 # patition number
  echo n # add a new partition
  echo p # primary partition
  echo 2 # partition number
  echo   # first sector (accept default: varies)
  echo +$size  # last sector
  echo w # write changes
  ) | fdisk /dev/mmcblk0
  err=$?
  if [ $err != 0 ]; then
    echo "fdisk failed, error: $err"
    exit 1
  fi


  # --------------------------------------------------------------

  # fill unused space with zeros
  echo "Do you want to fill unused space with zeros? [y/n]" 
  read fillzeros


  if [ "$fillzeros" = "y" ]
    then
      echo "Copy zeros. This will end up with an error. But this is ok."

      myMount    

      dd if=/dev/zero | pv | dd of=/tmp/sd2/nullen.datei conv=noerror,notrunc,sync bs=10240
      # exits with error -> this is normal

      # dlelete zeros
      rm -v -f /tmp/sd2/nullen.datei
      sync

      myUmount

    elif [ "$fillzeros" = "n" ]
      then
    echo "I don't delete anything."
    else
    echo "Sorry, I didn't understand."
    exit 1
  fi

  # --------------------------------------------------------------

  # find out end of partition
  fdisk -l /dev/mmcblk0
  echo "Please tell me the end of mmcblk0p2 displayed above."
  read count



  DATE=$(date +"%Y-%m-%d_%H%M")
  IMGFILENAME=$DATE.img 
  echo "Do you want to create image with filename $OUTPATH$IMGFILENAME? [y/n]"
  read answer
  if [ "$answer" = "y" ]
  then
    echo "Do you want to create a *.zip file of the created image? [y/n]"
    read zip
    echo "Do you want to enlarge partition 2 to maxsize after image creation? [y/n]"
    read enlarge

    echo "create image..."
    cd $OUTPATH
    # create image with dd, stop at and of partition
    # count=N   copy only N input blocks
    # bs=BYTES  read and write up to BYTES bytes at a time = block size
    # pv    show status
    dd if=/dev/mmcblk0 | pv -s $(( $count*512 )) | dd of=$IMGFILENAME bs=512 count=$count
    err=$?
    if [ $err != 0 ]; then
      echo "dd failed error: $err"
      exit 1
    fi

    # --------------------------------------------------------------
    # create zip file
    # or like this:
    # sudo dd if=/dev/sdX | pv |gzip > /pfad/zur/datei.img.gz
    if [ "$zip" = "y" ]
    then
      echo "create zip file..."
      zip $DATE.zip $IMGFILENAME
    fi
    # --------------------------------------------------------------
  fi

  # --------------------------------------------------------------
  # enlarge partition 2

  if [ "$enlarge" = "y" ]
  then
    myEnlarge
  fi

  ;; #end case mode backup
"restore")  ####################################### restore ####################################### 
  #chek if image exists
  if [[ -s "$DIRFILENAME" ]]
  then
    # check if file is an image or zip file
    if [[ $DIRFILENAME =~ \.img$ ]]
    then
      IMGFILENAME=$(basename "$DIRFILENAME")
    elif [[ $DIRFILENAME =~ \.zip$ ]]
    then
      ZIPFILENAME=$(basename "$DIRFILENAME")
    else
      echo "Not the right file format. I accept *.img and *.zip"
      exit 1
    fi
  else
    echo "Image file does not exist."
    exit 1
  fi
  echo "the file $DIRFILENAME will be restored to the SD Card /dev/mmcblk0"

  #change to the path of the imagefile
  SOURCEPATH=$(dirname "$DIRFILENAME")
  cd $SOURCEPATH


  if [ "$ZIPFILENAME" != "" ]
  then
    echo "unzip file"
    # change file extention form zip zu img
    l=$(( ${#ZIPFILENAME}-3 ))
    IMGFILENAME="${ZIPFILENAME:0:l}img"
    unzip $ZIPFILENAME
  fi

  echo "Do you realy want to restore $SOURCEPATH/$IMGFILENAME to the SD card /dev/mmcblk0? 
  Warning: all data on the device /dev/mmcblk0 will be lost! [y/n]"
  read answer
  if [ "$answer" = "y" ]
  then
    echo "Do you want to enlarge partition 2 to maxsize after restoring? [y/n]"
    read enlarge
    echo "restore image..."
    filesize=$(wc -c <"$IMGFILENAME")
    echo "Filesize = $filesize Byte"
    dd if=$IMGFILENAME | pv -s $filesize | dd of=/dev/mmcblk0 bs=512
    err=$?
    if [ $err != 0 ]; then
      echo "dd failed error: $err"
      exit 1
    fi
  fi

  # --------------------------------------------------------------
  # enlarge partition 2
  if [ "$enlarge" = "y" ]
  then
    myEnlarge
  fi

  ;; #end case mode restore
esac

0

La soluzione più semplice che ho trovato è stata quella di fare un backup della scheda più grande originale usando i comandi dd descritti sopra e quindi ripristinare l'immagine sulla scheda più piccola usando qualcosa come piwriter. dd potrebbe anche funzionare ... non sono sicuro. PiWriter ha restituito un errore poiché ha esaurito lo spazio, ma poiché l'immagine non conteneva dati effettivi oltre le dimensioni della scheda più piccola, stava semplicemente troncando i settori vuoti. Non sono sicuro di quali siano le implicazioni di questo ... potrebbe essere necessario verificare o riparare la partizione, ma posso verificare che abbia funzionato quando l'ho inserito nel Pi.


1
questo è un consiglio molto pericoloso, non saprai mai se c'erano effettivamente dati oltre la dimensione. stiamo cercando soluzioni più affidabili e collaudate per funzionare.
lenik,

Vivo pericolosamente, cosa posso dire;) In tutta serietà, anche se non ho molta esperienza di lavoro con le mappe di partizioni o dd, quindi sono in un territorio inesplorato qui. Probabilmente sono stato fortunato dato che avevo solo circa 800 MB di dati che vanno da una scheda da 16 GB a una scheda da 8 GB. Per curiosità, c'è un modo forse di deframmentare prima i dati per assicurarsi che siano tutti raggruppati all'inizio della partizione? Sembra hacker ma forse?
Cane

non so deframmentare, ma sicuramente potresti ridimensionare le tue partizioni e spostarle all'inizio della scheda SD, quindi occupano solo l'inizio. richiede un po 'più di tempo rispetto al semplice dd, ma i risultati sono molto più affidabili.
Lenik,

0

Uso una vecchia versione di win32diskimager-RELEASE-0.1-r15-win32per leggere l'immagine, crea un'immagine di 4 GB anche da una scheda SD da 8 GB e quindi scrive l'immagine con l'ultima versione di win32diskimager.

Uso la versione precedente perché la vecchia salterà ogni errore.


Non esiste un'opzione nella nuova versione, 0.95, che ti consente di fare lo stesso, ovvero di saltare ogni errore? Sfortunatamente la pagina sourceforge non sembra elencare nessuna delle opzioni disponibili. Sembra solo leggermente rischioso usare il software pre-beta
Greenonline il

Non ricevo alcun calore e confusione dall'uso di un programma che salterà ogni errore.
RufusVS,
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.