Contexto
Eu tenho um cartão SD de 16 GB com um sistema operacional baseado em Linux para um Raspberry Pi. A maior parte do espaço está vazio.
Eu quero compartilhar o SD .img
com outras pessoas, mas se eu usar o comando
dd if=/dev/sdXX of=/home/user123/SD.img
ele criará uma imagem de 16 GB. Muito grande.
Pergunta
Como posso redimensionar uma imagem de cartão SD de 16 GB para um tamanho menor de 4 GB?
Eu tentei com o GParted: ele cria uma partição com 4GB sem problemas, porém todo .img
o cartão SD continua sendo 16GB com 12GB de espaço não alocado.
Eu li a pergunta e resposta Cloning multiple partitions in Ubuntu , mas ainda não consigo redimensionar o cartão SD de 16 GB em um de 4 GB.
Mais informações
~$ lsblk
...
sdc 8:32 1 14,9G 0 disk
├─sdc1 8:33 1 100M 0 part
└─sdc2 8:34 1 4G 0 part
~$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 14,9 GiB, 15931539456 bytes, 31116288 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
Disklabel type: dos
Disk identifier: 0xf8a631ce
Device Boot Start End Sectors Size Id Type
/dev/sdc1 * 2048 206847 204800 100M c W95 FAT32 (LBA)
/dev/sdc2 206848 8595455 8388608 4G 83 Linux
Qualquer conselho é apreciado!
Observe : conforme observado por Melebius em um comentário , a palavra certa a ser usada é encolher :
Você não pode redimensionar um cartão SD, pois é um hardware com uma determinada capacidade que não pode ser alterada. Você claramente deseja reduzir uma imagem do cartão SD .
Este artigo fornece uma solução que resolve meu problema (*). É bem parecido com o outro, mas explica melhor como calcular e qual o significado dos números e das partições.
A informação chave foi o uso do comando
truncate
. Seguindo a solução completa para não perder a resposta.Um passo preliminar consiste em clonar o cartão SD no seu PC:
use
lsblk
para ver quais dispositivos estão disponíveis e se suas partições estão montadasdesmonte todas as partições do dispositivo que você deseja copiar no seu PC. Por exemplo:
crie uma cópia de todo o cartão SD com todas as partições desmontadas
Encolher imagens no Linux
Contexto do problema :
Ter um
myimage.img
maior que o suporte de hardware (se for menor não deve haver problema; porém, usando a mesma estratégia, você pode encaixar melhor a imagem no suporte de hardware).O segredo é usar ferramentas e instrumentos padrão do Linux: GParted
fdisk
etruncate
.Requisitos :
.img
que você deseja reduzir (myimage.img
neste exemplo)Criando dispositivo de loopback :
GParted é um aplicativo normalmente usado para gerenciar tabelas de partição e sistemas de arquivos. Para reduzir a imagem, o GParted será usado na primeira parte da resposta.
Vamos habilitar habilitar o loopback:
Vamos solicitar um novo dispositivo de loopback (gratuito):
O comando retorna o caminho para um dispositivo de loopback livre:
Vamos criar um dispositivo da imagem:
O dispositivo
/dev/loop0
representamyimage.img
. Queremos acessar as partições que estão na imagem, então precisamos pedir ao kernel para carregá-las também:Isso deve nos dar o dispositivo
/dev/loop0p1
, que representa a primeira partição emmyimage.img
. Não precisamos desse dispositivo diretamente, mas o GParted o exige.Redimensione a partição usando GParted :
Vamos carregar o novo dispositivo usando o GParted:
Quando o aplicativo GParted for aberto, deverá aparecer uma janela semelhante à seguinte:
Agora observe algumas coisas:
Queremos redimensionar esta partição para que ela se ajuste ao seu conteúdo, mas não mais do que isso.
Selecione a partição e clique em Redimensionar/Mover. Aparecerá uma janela semelhante à seguinte:
Arraste a barra direita para a esquerda o máximo possível.
Observe que às vezes o GParted precisará de alguns MB extras para colocar alguns dados relacionados ao sistema de arquivos. Você pode pressionar a seta para cima na caixa Novo tamanho algumas vezes para fazer isso. Por exemplo, pressionei 10 vezes (= 10MiB) para que o FAT32 funcionasse. Para NTFS, talvez você nem precise.
Por fim, pressione Redimensionar/Mover. Você retornará à janela do GParted. Desta vez, será semelhante ao seguinte:
Observe que há uma parte do disco não alocada. Esta parte do disco não será usada pela partição, então podemos remover esta parte da imagem mais tarde. GParted é uma ferramenta para discos, por isso não encolhe imagens, apenas partições, temos que fazer o encolhimento da imagem nós mesmos.
Pressione Applyno GParted. Ele agora moverá os arquivos e finalmente reduzirá a partição, de modo que pode levar um minuto ou dois, mas na maioria das vezes termina rapidamente. Depois feche o GParted.
Agora não precisamos mais do dispositivo de loopback, então descarregue-o:
Rasgando a imagem :
Agora que temos todos os dados importantes no início da imagem, é hora de cortar essa parte não alocada. Primeiro precisaremos saber onde nossa partição termina e onde começa a parte não alocada. Fazemos isso usando
fdisk
:Aqui veremos uma saída semelhante à seguinte:
Observe duas coisas na saída:
End
)1 * 512
)Usaremos esses números no restante do exemplo. O tamanho do bloco (512) geralmente é o mesmo, mas o bloco final (9181183) será diferente para você. Os números significam que a partição termina no byte 9181183 512 do arquivo. Depois desse byte vem a parte não alocada. Apenas os primeiros 9181183 512 bytes serão úteis para nossa imagem.
Em seguida, reduzimos o arquivo de imagem para um tamanho que possa conter apenas a partição. Para isso vamos usar o
truncate
comando (obrigado uggla!). Com o comando truncate precisa fornecer o tamanho do arquivo em bytes. O último bloco foi 9181183 e os números de bloco começam em 0. Isso significa que precisamos de (9181183+1)*512 bytes. Isso é importante, caso contrário a partição não caberá na imagem. Então agora usamos truncate com os cálculos:(*) parece que o post original de FrozenCow foi movido para aqui .
Você pode usar as opções
bs
ecount
nodd
comando - para limitar o tamanho do arquivo de saída.Exemplo:
resultaria em um arquivo de saída com um tamanho de 4 GiB.
Dê uma olhada profunda em
man dd
.Você precisaria saber quantos bytes você precisa copiar para que todas as partições sejam totalmente cobertas, então dê uma olhada em
sudo fdisk -l /dev/sdx
qual setor é o último que você precisa.As partições precisam estar no início do disco (como na imagem que você forneceu).
Discos com tabela de partição msdos podem ser clonados facilmente desta forma, mas se o disco usa GPT e deve ser clonado em um disco com tamanho diferente, o MBR protetor precisa ser adaptado posteriormente e o backup GPT que reside no próprio final do disco precisa ser recriado, isso pode ser feito com
gdisk
.A partir do seu
fdisk
-output, você pode ver que o último setor da última partição é o setor8595455
, o que significa que você deve copiar pelo menos 8595455+1 setores (o primeiro setor é 0). Com um tamanho de setor de 512 bytes, isso é igual a 4.400.873.472 bytes.bs
multiplicado porcount
tem que ser maior ou igual a isso.Talvez isso ainda seja muito grande para um pendrive de 4 GB, você ainda pode reduzir o tamanho do
sdc2
, há muito espaço não utilizado nele.Para o exemplo atual que você forneceu,
cobrirá a tabela de partições
sdc1
esdc2
. Calcular:resize2fs
também pode ser usado para redimensionar isso.Ele também redimensiona o próprio arquivo!
A resposta selecionada se aplica perfeitamente ao tipo disklabel dos . Para o tipo GPT , é preciso considerar a adição de 33 setores, pois o GPT armazena uma tabela também no final do disco.
Portanto, para usuários do GPT, os comandos 'truncate' precisam ser assim:
truncate --size=$[( End_of_last_partition + 1 + 33 )*512] myimage.img
Isso deve produzir um erro GPT em
fdisk -l
. Para corrigir isso, execute o seguinte:Execute o comando para verificar o disco:
v
. Você deve ver alguns erros encontrados no disco."No gdisk, você digitaria x para entrar no menu de especialistas, depois digitaria e para mover os dados da tabela de partição de backup para a nova extremidade do disco e, em seguida, digitaria w para gravar as alterações no disco." [Fonte] como truncar um arquivo de imagem de disco de espaço não utilizado sem corromper a tabela de partição GPT (ponteiro final) - Obrigado!
Examinei muitos dos métodos aqui e entendi todos eles, mas as etapas eram algo que eu não estava ansioso para fazer ao ter que executá-las para simplesmente reduzir um arquivo IMG do Raspberry Pi. Então, procurando, me deparei com esse script Bash de um projeto chamado PiShrink .
Foi bastante trivial de executar e funcionou no meu MacOS M1 Mac Mini para inicializar.
História de fundo
No meu caso particular, eu tinha 2 cartões SD de 32 GB e, por qualquer motivo, 1 era ligeiramente (~ 95 MB) menor que o outro e balenaEtcher se recusou a escrever o IMG do que parecia ser o maior dos 2 cartões SD para o menor.
Eu sabia que estava usando apenas ~ 10 GB dos 32 GB para poder reduzir o arquivo IMG para caber.
Passos
To start I had the following files. The
.zip
file contained the.img
file but I'm showing it unzipped from it below.I then downloaded the PiShrink shell script and made it executable:
I then ran it like so:
The resulting IMG file is now ~9GBs.
I then repackaged it as a ZIP file just so that it was kept in the most efficient size possible while dealing with it on disk.
We now have the following set of files kicking around:
I can then use balenaEtcher or ApplePi-Baker to burn the ZIP file to the "smaller" SD card.
Poking at the SD card on my Mac I can see it's showing ~10GB.
NOTE: I could do the same commands from a Linux system using
lsblk
etc..Post Ops
Eu notei depois de usar o método acima que o sistema de arquivos no cartão SD estava com 32 GB completos. Principalmente mostrou assim:
Isso deve ser facilmente resolvido expandindo o sistema de arquivos SD de dentro depois de inicializá-lo.
Para iniciar isso, primeiro uso
parted
para estender a partição:Então reiniciei o sistema:
Depois que eu online expandi o sistema de arquivos usando
resize2fs
:E agora mostra todo o espaço livre no cartão SD: