Como criar uma imagem (.img) do que está no cartão SD (mas tão compacto quanto o original)?

20

Eu tentei:

sudo dd bs=4k if=/dev/mmcblk0 of=/media/1BAB47551C66A42B/raspbian_migs2.gz

Ele cria um arquivo .img com 7,6 GB (tamanho do cartão, MAS o que há no cartão tem 700 MB).

E:

sudo dd bs=4k if=/dev/mmcblk0 | gzip > /media/1BAB47551C66A42B/raspbian_migs2.gz

cria um arquivo .gz com 2,7 GB.

O Raspbian original ( Debian 7 (Wheezy)) de http://www.raspberrypi.org/downloads possui 494,44 MiB.

Pelo que há no cartão SD, como posso criar uma imagem de tamanho semelhante?

(Estou no Ubuntu.)

mf_
fonte
raspberrypi.stackexchange.com/questions/311/... esta ajuda não funcionavam
mf_

Respostas:

18

Você mencionou em um comentário ao RooTer que A) reduziu o tamanho da partição inicial gparted, mas ddainda copia o cartão inteiro e B) que deseja incluir as duas partições na imagem.

É fácil explicar o problema "A": você ainda está copiando o cartão inteiro porque é isso que /dev/mmcblk0se refere. As partições individuais são obviamente /dev/mmcblk0p1e /dev/mmcblk0p2. Essa é a complicação do problema "B", mas você não pode simplesmente ddcada partição e concatenar os dois arquivos juntos, porque a tabela de partições no início /dev/mmcblk0 indexa o início e o comprimento de cada partição. Sem isso, a imagem será inutilizável.

No entanto, você pode obter o comprimento de cada partição fdisk -le usá-lo para determinar alguns parâmetros para dd. Por exemplo:

> fdisk -l /dev/mmcblk0

Disk /dev/mmcblk0: 16.1 GB, 16138633216 bytes
4 heads, 16 sectors/track, 492512 cylinders, total 31520768 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: 0x00017b69

Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1    8192      122879       57344    c  W95 FAT32 (LBA)
/dev/mmcblk0p2  122880    26746879    13312000   83  Linux

As unidades "Iniciar" e "Final" são setores e observe o tamanho do setor, 512 bytes. Para /dev/mmcblk0p2, 26746879 (o último setor) - 122880 (o primeiro setor) = 26623999/2 (para 2 setores por kB) / 1024 (kB por MB) / 1024 (MB por GB) = 12,69, que eu ampliei a partição usando gparted para 12 GB, então isso parece correto (realmente eu deveria estar usando 1000 e não 1024 como o divisor com armazenamento, o que resulta em 13,31 GB, mas eu suspeito que o gparted e algumas outras ferramentas também usam 1024).

Portanto, a primeira coisa que você deseja verificar é que sua segunda partição é realmente o tamanho menor que você a configurou. Em seguida, basta usar esses números com dd; para mim seria:

dd if=/dev/mmcblk0 of=rpi.img bs=512 count=26746880

Eu tenho um setor extra lá para evitar qualquer tipo de desentendimento por um mal-entendido de como ddfunciona. Existe uma maneira simples de verificar se isso funcionou:

> fdisk -l rpi.img

Disk rpi.img: 102 MB, 102400000 bytes
255 heads, 63 sectors/track, 12 cylinders, total 200000 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: 0x00017b69

Device Boot      Start         End      Blocks   Id  System
rpi.img1          8192      122879       57344    c  W95 FAT32 (LBA)
rpi.img2        122880    26746879    13312000   83  Linux

Observe que há uma discrepância aqui: os setores "Iniciar" e "Final" correspondem à tabela de partição original, mas o tamanho total das estatísticas no topo é de apenas 102 MB! Isso porque eu realmente usei count=200000o parâmetro ddporque realmente não queria me preocupar com uma cópia de 12 GB (observe também "total de 200000 setores"). A razão pela qual a tabela na parte inferior não reflete isso é porque o fdisk está obtendo suas informações dos dados da partição copiados literalmente no início da imagem desde o início do cartão SD, o que, como mencionei no segundo parágrafo, é vital manter. Se eu tivesse (adequadamente) copiado o resto, os números seriam copacéticos e a imagem seria viável.

Faça uma tentativa. :)

Cachinhos Dourados
fonte
No OSX, o fdisk não imprime claramente o tamanho do setor em bytes. Em vez disso, oferece "geometria: 966/255/63 [15523840 setores]" representando cilindros / cabeças / setores. Quais valores de bs e count devem ser usados ​​neste caso?
Arthur Hebert 21/01
@ArthurHebert: total de bytes / total de setores. Por exemplo, no primeiro caso acima, seria 16138633216/31520768 = 512, no segundo 102400000/200000 = 512.
goldilocks
1
Você pode usar fdisk -l <device>e isso deve imprimir a tabela sem entrar no modo interativo.
berto
5

Eu acho que o problema está nos setores usados ​​uma vez que ainda têm sujeira neles. Depois que o arquivo é excluído, apenas os metadados são removidos do sistema de arquivos, não os dados em si, deixando alguns zeros aleatórios em vez de fáceis de compactar blocos com zero.

Solução fácil, mas requer reescrever todo o espaço livre no cartão. Lembre-se de que o tempo de vida do cartão SD é limitado pelo número de reescritas, portanto, este não é o método preferido.

dd bs=4M if=/dev/zero of=/root/junk
sync
rm junk

Solução mais envolvente, pois você precisa instalar o zerofree em outro computador que não utilizará esse cartão SD no momento.

zerofree /dev/mmcblk0p2

Para mais informações, consulte http://intgat.tigress.co.uk/rmy/uml/index.html

O que você deve se lembrar é que, ao executar o dd de / dev / mmcblk0, você copia o dispositivo inteiro, mesmo que as partições sejam menores. Se você usou o raspi-config para expandir a partição principal antes de executar um dos métodos acima, você estará bem.

PS Se você não se importa em alterar o arquivo de imagem formatada, pode usar a partimage que, para sistemas de arquivos conhecidos, omite blocos liberados, mesmo que eles ainda tenham alguma sujeira. Novamente, partimage é melhor ser usado quando o sistema de arquivos não estiver montado para evitar a corrupção do backup. Provavelmente você pode voltar a montá-lo como somente leitura, mas deixarei a seu critério.

RooTer
fonte
como parte da minha busca para tentar fazer isso, usei o gparted para reduzir a partição sdcard para acomodar apenas os dados que tenho, então tentei o dd ing e os resultados são o mesmo arquivo de 7,6 GB, a partimage não pode salvar 2 partições (/ boot + /) em 1 imagem
mf_
talvez eu não tenha deixado claro o suficiente - deve fazer a diferença quando você o comprime, como você tentou com o gzip antes.
RooTer 07/07
encher o cartão dessa maneira causará vários ciclos de gravação e reduzirá a vida útil do cartão. tentedd bs=4M if=/dev/zero of=/root/junk
nc4pk
@ thped-out thx, editado;)
RooTer 11/07
4

Resposta curta - use cartão SD de 2 GB.

Resposta longa, ddnão tem idéia de onde os dados "bons" terminam, você precisa contar de alguma forma.

Existem duas maneiras, a mais fácil é usar o cartão SD de 2 GB, que interromperá automaticamente a cópia além de 2 GB e resultará em 500 MB de arquivo compactado, conforme desejado.

A outra maneira, mais complicada e envolvida, é calcular o tamanho correto dos dados da sua tabela de partição e especificar esse tamanho correto como parâmetros a serem ddcomandados. Você pode usar os parâmetros bs=XXX(tamanho do bloco) e count=XXX(contagem de blocos) para esse fim. Por exemplo, você pode especificar um bs=10Mtamanho de bloco de 10 MB (que definitivamente tornaria a cópia muito mais rápida em comparação com o tamanho de bloco de 4 count=200k usado em seus comandos) e copiar 10 MB * 200 = 2000 MB (2 GB). Pode ser necessário ajustar o tamanho e a contagem de blocos de acordo com o esquema de partição do cartão SD .

lenik
fonte
1
Dar ddum tamanho específico NUNCA funcionará. Isso pressupõe que todos os dados reais no sistema de arquivos estejam organizados no início do dispositivo; portanto, se você possui 2 GB em uma partição de 8 GB, basta copiar os primeiros 2 GB. Isto é falso. Esses 2 GB de dados serão espalhados por todo o espaço, especialmente em cartões SD modernos que não reutilizam blocos duas vezes até que todos os blocos disponíveis tenham sido usados ​​pelo menos uma vez (isso é chamado de nivelamento por desgaste e prolonga a vida útil do cartão).
goldilocks
@goldilocks e se eu redimensionar o sdcard para reduzir todas as partições para o tamanho máximo possível (apenas dados)?
Mf_
@ goldilocks, por favor, leia a pergunta e a resposta com mais cuidado. Estou falando da partição de 2 GB em um cartão SD de 8 GB, e não de dados de 2 GB na partição de 8 GB, como sua imaginação selvagem lhe disse.
117813
1
lenik: Sim, estou um pouco aturdido por ter interpretado você dessa maneira, desculpas - infelizmente não posso reverter meu voto negativo, a menos que você edite o post: / embora eu ainda não ache essa resposta particularmente útil (sem ofensas - - porque isso não é simplesmente criar uma partição , instruções sobre como fazer isso não são mais úteis), mas farei isso. @mf_ Sim, isso é factível (? você leu minha resposta Ele vai trabalhar ...)
goldilocks
@goldilocks Eu editei a resposta. Não sei por que não é útil, especialmente quando você deu exatamente a mesma resposta, apenas com mais detalhes.
111313
1

dd - copy and convertnão é a ferramenta certa para realizar o trabalho solicitado. É uma ferramenta de baixo nível, setor a setor, que copia (e converte), ideal para copiar setores de inicialização, formatar dispositivos e todo tipo de tarefas de baixo nível. Ao usar, ddvocê está copiando setor por setor para a imagem, mesmo que ela não esteja incluída na Estrutura do sistema de arquivos.

As imagens fornecidas pela fundação Raspberry Pi são especialmente compiladas com scripts de instalação, descompactando binários e configuração inicial, após o qual você precisa obter atualizações da Internet de qualquer maneira - o que é deliberado, mas é uma tarefa bastante necessária para que funcione dessa maneira.

Uma solução popular para evitar a cópia de setores vazios é usar um sistema de cópia no nível de arquivo - e o CloneZilla é autônomo, inicializável a partir de um CD, semelhante ao ye olde Norton Ghostclonezilla, mas que suporta o sistema de arquivos Linux (e mais). Portanto, ele copiará apenas os arquivos que estão em uso e criará um contêiner somente a partir desses arquivos. Reduz significativamente o tamanho!

Piotr Kula
fonte
1

Eu tinha essa mesma pergunta exata e queria uma ferramenta fácil de usar. Depois de pesquisar e não encontrar um, escrevi mkimg.sh . Descrevo o processo que usei em: /raspberrypi//a/37899/32585

berto
fonte