Copie a instalação Raspbian existente para um cartão SD menor


25

É possível copiar uma instalação Raspbian existente e configurada em um cartão SD menor?

Quando instalei o Raspbian pela primeira vez, eu tinha apenas um cartão de 32 GB em mãos, o que obviamente é maior que o necessário.


O sistema funcionará melhor e o cartão durará mais tempo com mais espaço livre em sua partição primária. Portanto, não reduza muito - mantenha pelo menos o dobro do uso (por exemplo, se o sistema tiver 2-3 GB, use um Cartão de 8 GB e aumente a partição para preencher todo o espaço disponível). Observe que, se você não expandiu a partição, ela não será de 32 GB; portanto, talvez você não precise reduzi-la.
goldilocks

Obrigado por apontar isso, mas atualmente meu Raspberry está usando apenas 1,8 GB, porque é uma instalação realmente básica. Então eu acho que 4 GB deve ser suficiente.
Mwld # 6/13

Eu acho que eu cresci até o tamanho máximo quando instalei o Debian Wheezy. Agora encolhi para 2,5 GB, mas ainda não obtive sucesso. Veja meus comentários abaixo.
mwld 6/13


11
Se uma das respostas abaixo satisfizer sua pergunta, verifique a resposta.
18730 Wes Modes

Respostas:


12

Nesta resposta, demonstro o que fazer passo a passo para que as pessoas entendam a lógica por trás da solução e sejam capazes de aplicar etapas em outros problemas.

Mas, em primeiro lugar, deve-se afirmar que é um problema genérico (não específico para raspi) migrar sistemas de arquivos de um cartão SD para um cartão SD menor (mas grande o suficiente para dados).

Exigências

Um laptop com um leitor de cartão micro SD e Linux (eu prefiro o Ubuntu) rodando nele.

Abreviações

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

Partições do SD_CARD_A

Enquanto o PIBOX está em execução, listamos as partições (partições desnecessárias do sistema não estão sendo exibidas aqui).

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

Existem 2 partições no SD_CARD_A como /e /boot. Mesmo 2 GB não são utilizados no total.

Backup SD_CARD_A

Depois de desligar e interromper o PIBOX, retiramos o SD_CARD_A da placa do PIBOX e o colocamos no leitor de cartão do nosso laptop.

As partições do SD_CARD_A são montadas automaticamente em nosso sistema como /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

Desmontamos essas partições do nosso sistema para operá-las com sucesso.

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

Exibimos as informações do dispositivo de SD_CARD_A em detalhes para confirmações nas próximas etapas.

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

Acima, você pode ver que SD_CARD_A tem capacidade de 8 GB.

Nós clonamos SD_CARD_A no arquivo 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

Verifique o tamanho dos bytes copiados, é igual ao valor que obtivemos por fdisk -l /dev/sdccomando.

Módulo de loopback do Linux

O Linux possui um módulo chamado loopback, que nos permite manipular um arquivo como um dispositivo de bloco.

Carregamos o módulo de loopback.

root@mylaptop:~# modprobe loop

Encontramos um caminho de dispositivo de loopback não utilizado.

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

Agora, criamos um dispositivo de loopback para o arquivo pibox.img.

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

Nós acionamos o kernel sobre mudanças na partição.

root@mylaptop:~# partprobe /dev/loop0

Confirmamos se as operações anteriores foram bem-sucedidas.

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

Exibimos as informações do dispositivo de loopback em detalhes para compará-las com 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

Acima, você pode ver que o tamanho do dispositivo de loopback (= 7969177600 bytes) e as partições são iguais aos SD_CARD_A.

Matemática Básica

A partir de agora, estaremos focados na partição /dev/loop0p2. Vamos chamá- lo de THE_PARTITION .

O tamanho do bloco é de 512 bytes (conforme impresso na linha que começa com Units = setores .....)

THE_PARTITION começa no bloco 137216 e termina no bloco 15564799, o que significa que possui o tamanho de 15427584 blocks(= 15564799 - 137216 + 1).

Portanto, o tamanho de THE_PARTITION em bytes é 7898923008 bytes(= 512 * 15427584).

Para ajustar THE_PARTITION em SD_CARD_B, queremos que ele tenha um novo tamanho 3710940 blocks ou em outras palavras 1900001280 bytes(= 512 * 3710940).

Portanto, o novo número do bloco final é 3848155calculado por start block number(= 137216) + size in blocks(= 3710940) - 1.

Sistema de arquivos vs. partição

Existem 2 operações que não devem ser confundidas.

  • Redimensionando sistema de arquivos. Reduziremos o sistema de arquivos em THE_PARTITION, definindo seu tamanho para 3710940 blocks.
  • Redimensionando partição. Reduziremos THE_PARTITION definindo o número do bloco final como 3848155.

Encolhendo o sistema de arquivos

Antes de reduzir o sistema de arquivos, ele deve ser marcado como limpo 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

Encolhemos o sistema de arquivos 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.

Partição encolhendo

Aprendemos com o que é o número 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

Encolhemos THE_PARTITION com 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  

Terminamos com o dispositivo de loopback. Nós destacamos.

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

Truncar arquivo de imagem

Verificamos a nova tabela de partição.

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

Na saída, é claramente visto que o número do bloco final de THE_PARTITION é diminuído from 15564799 to 3848155.

O último bloco que usamos é 3848155. A numeração dos blocos começa em 0. Portanto, temos 3848155 + 1 blocos no total e o novo tamanho do arquivo pibox.img deve ser 1970255872 bytes (= (3848155 + 1) * 512).

Truncamos o arquivo pibox.img.

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

Verificamos o novo tamanho do arquivo pibox.img.

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

Criando SD_CARD_B

Colocamos SD_CARD_B no leitor de cartão do nosso laptop. As partições do SD_CARD_B são montadas automaticamente em nosso sistema como /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

Acima, você pode ver que SD_CARD_B tem capacidade de 2 GB.

Desmontamos essas partições do nosso sistema para operar com sucesso no SD_CARD_B.

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

Clonamos o arquivo pibox.img no 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

Verifique o tamanho dos bytes copiados, é igual ao valor que obtivemos por ls -l pibox.imgcomando.

Inicializando o PIBOX

Depois de retirar o SD_CARD_B do laptop e colocá-lo na placa PIBOX, inicializamos o sistema e efetuamos login no console do PIBOX.

Listamos as partições (algumas outras partições desnecessárias do sistema não estão sendo exibidas aqui).

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

Um bom. Eu acho que algumas das suas coisas com a configuração do loopback podem ser demoradas e desnecessárias, talvez você queira verificar isso. Algo muito semelhante a partir de uma pergunta muito semelhante: raspberrypi.stackexchange.com/a/29952/5538
goldilocks

@ goldilocks, não testado, mas acho que é necessário usar o loopback. Tanto quanto sei que o parted não pode funcionar diretamente no arquivo de imagem, ele precisa de uma interface de dispositivo para suas operações.
vaha

Sim, mas acho que você descobrirá que não precisa se preocupar losetupnem com isso -o loop=whatever. Conforme o outro post, eu apenas uso mount -o offset=123 /imagefilepath /mntpointe o uso de loopback está implícito. Eu presumo que isso geralmente é verdade no Linux agora - tente e veja. Você pode reduzir isso para apenas dizer que as partições são montadas através de um "dispositivo de loopback" virtual.
goldilocks

5

Quando você usa dd if=/dev/sdx of=/path/to/image bs=1M, /dev/sdxrefere-se a todo o "disco", para que a imagem sempre tenha o tamanho de todo o cartão.

Em vez disso, você precisaria usar dd if=/dev/sdxn ...onde nestá o número da partição.

Você provavelmente precisará fazer isso duas vezes - uma para a /bootpartição e outra para a /partição.

Em seguida, você precisará criar partições no novo cartão que sejam pelo menos tão grandes quanto as duas originais, para recuperar o conteúdo.


3

Use algo como parted (editor de partições) para reduzir a partição primária para um tamanho menor e use uma ferramenta como o Clonezilla para copiar da partição agora menor para o seu novo cartão. Você provavelmente precisará fazer isso em outro computador.


Infelizmente isso não funcionou. Encolhi a partição para 2,5 GB com o GParted. Mas quando tentei criar uma imagem a partir de um dispositivo USB, ele ficou muito maior (4,3 GB - mas acho que queria copiar todos os 32 GB e parei em 4,3 GB devido à limitação do tamanho do arquivo FAT).
Mwld 6/13

2
Eu usei o comando dd if=/dev/sdx of=/path/to/image bs=1Mdeste segmento: raspberrypi.stackexchange.com/questions/311/…
mwld

Você tem alguma idéia de como eu posso copiar a partição primária com 2,5 GB em uma imagem e ainda criar um cartão SD com Raspbian inicializável?
Mwld 6/13

Desculpe pela resposta tardia. Comecei com um cartão SD de 4 GB, criei uma imagem e depois a escrevi em cartões de 8 GB e maiores. Ainda não precisei usar uma partição maior para qualquer coisa em que trabalhei. Não conheço uma ferramenta que permita criar uma imagem de uma partição individual em um cartão SD.
Jerry Gagnon

3
  1. Crie uma imagem do cartão usando um dos métodos já mencionados - Como faço para fazer backup do meu Raspberry Pi?

  2. Use o script em http://sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer/ para reduzir o tamanho da imagem

  3. Restaurar a imagem reduzida em um novo cartão menor


Eu encontrei esta página porque estou tentando atingir o mesmo objetivo de ter backup da minha imagem raspbian, no entanto, não quero o cartão inteiro SOMENTE dados relevantes no cartão. Conforme a sugestão acima, eu estava procurando pelo script aqui sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer, mas não consegui encontrar um. alguém poderia atualizar este link se estiver disponível em algum lugar?
Shallyverma 13/10

Ainda consigo acessar o link e o post em si é um script. Copie o script em um arquivo e atribua um nome script.sh, Torne o arquivo executável usando chmode execute-o.
Mihir

1

Eu tenho usado rsyncpara copiar sistemas de arquivos de um disco para outro por um tempo agora, sem soluços. A vantagem de usar o rsync é que ele está copiando o conteúdo do sistema de arquivos, em vez de fazer uma cópia do dispositivo em nível de bloco; como resultado, ele realmente não se importa com o tamanho das unidades de destino e de origem, desde que a unidade de destino tenha espaço suficiente para armazenar os dados.

Então, aqui está como eu faria isso:

  1. Crie uma nova instalação raspbian no seu novo cartão SD menor e desejado.
  2. Inicialize na nova instalação e expanda o sistema de arquivos para preencher todo o disco. Desligue o pi.
  3. Agora monte os cartões novos e antigos e use rsync -avx oldFilesystem newFilesystempara copiar / substituir o sistema de arquivos no novo cartão pelo sistema de arquivos do cartão antigo.
  4. Por fim, inicialize em seu novo sistema e execute rpi-updatepara garantir que seu firmware seja consistente e atualizado.

Depois disso, sua nova placa deve ter um sistema Raspbian perfeitamente funcional instalado.


Então, para este método (Etapa 3), preciso de 2 leitores de cartão SD?
Victor Van Hee

Dois leitores de cartão SD ou um dispositivo intermediário. Você pode sincronizar novamente o sistema de arquivos antigo em uma pasta do disco rígido e depois sincronizá-la no segundo cartão SD, se não quiser pegar um leitor.
Sdenton4

1

Eu criei um script de shell para fazer backup e restaurar todos os dados em um cartão SD. Ele primeiro exclui alguns dados (correspondentes ao meu projeto) e reduz a partição ao tamanho mínimo, para que a imagem seja tão grande quanto os dados no cartão SD. Além disso, o script cria um arquivo * .zip da imagem. Após restaurar a imagem criada para outro cartão SD, a partição será ampliada para o tamanho máximo. O script usa os comandos mencionados nas outras respostas. Como esse é o meu primeiro script de shell com esse tamanho, levei horas para criá-lo e não é um jato perfeito. Especialmente, não sei como lidar com os valores de retorno de resize2fs e fdisk, para que o usuário precise digitar os valores de que preciso. Há alguma idéia para consertar isso? Espero que este script ajude outra pessoa. Sinta-se livre para editar e aprimorá-lo.

"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

Aqui está:

#!/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

A solução mais fácil que encontrei foi fazer um backup do cartão maior original usando os comandos dd descritos acima e, em seguida, restaurar a imagem no cartão menor usando algo como piwriter. dd pode funcionar tão bem ... não tenho certeza. O PiWriter retornou um erro porque ficou sem espaço, mas como a imagem não continha dados reais além do tamanho do cartão menor, estava apenas truncando setores vazios. Não sei ao certo quais são as implicações disso ... a partição pode precisar de verificação ou reparo, mas posso verificar se funcionou quando o coloquei no Pi.


11
este é um conselho muito perigoso, você nunca saberá se realmente existem dados além do tamanho. estamos procurando soluções mais confiáveis ​​e comprovadas para o trabalho.
lenik

Eu vivo perigosamente, o que posso dizer;) Com toda a seriedade, embora eu não tenha muita experiência trabalhando com mapas de dd ou partição, estou em um território desconhecido. Provavelmente tive sorte, pois só tinha cerca de 800 MB de dados, passando de um cartão de 16 GB para um cartão de 8 GB. Por curiosidade, existe alguma maneira de talvez desfragmentar os dados primeiro para garantir que todos estejam agrupados no início da partição? Parece hackish, mas talvez?
Pooch

Eu não sei sobre desfragmentação, mas você definitivamente pode redimensionar suas partições e movê-las para o início do cartão SD, para que elas ocupem apenas o começo. demora um pouco mais do que o dd simples, mas os resultados são muito mais confiáveis.
18714 lenech

0

Eu uso uma versão antiga do win32diskimager-RELEASE-0.1-r15-win32para ler a imagem, ele cria uma imagem de 4 GB mesmo a partir de um cartão SD de 8 GB e depois grava a imagem com a versão mais recente do win32diskimager.

Eu uso a versão mais antiga porque a anterior irá pular todos os erros.


Não existe uma opção na nova versão, 0,95, que permita fazer o mesmo, ou seja, pular todos os erros? Infelizmente, a página sourceforge não parece listar nenhuma das opções disponíveis. Parece apenas ligeiramente arriscado usando o software pré-beta
Greenonline

Não recebo elogios por usar um programa que irá pular todos os erros.
RufusVS
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.