Como redimensionar um arquivo de imagem antes de gravar no cartão SD?

13

Eu tenho tentado criar uma nova imagem Raspbian com um kernel diferente (com suporte para CAN) e com o Python 3.3 instalado. Em vez de fazer tudo isso no Raspberry Pi, achei interessante fazê-lo no computador (seguindo estas instruções ). No entanto, depois que a imagem foi montada e pronta para uso, fiquei rapidamente sem espaço em disco. Eu presumo que isso ocorre porque a imagem é dimensionada para ser grande o suficiente apenas com a expectativa de que o usuário redimensione o sistema de arquivos depois de gravado em um cartão SD.

É possível redimensionar a imagem e o sistema de arquivos antes de gravá-lo no cartão SD para que eu possa fazer mais personalização sem ficar sem espaço?

DrAl
fonte
Esta pergunta provavelmente o ajudará.
Jivings
1
@Jivings: todas essas respostas descrevem como redimensionar a imagem depois que ela foi gravada no cartão SD. Eu sei como fazer isso; Estou interessado em como redimensionar a imagem antes de gravá-la no cartão SD.
DrAl

Respostas:

7

Isto é como redimensionar um arquivo de imagem bruto. Eu sei que parece estupidamente simplista, mas vai funcionar.

Crie uma imagem em branco, do tamanho que você deseja expandir o original (no meu exemplo eu uso 5 GB);

dd if=/dev/zero of=/path/to/temp_image bs=1 count=1 seek=5G

Acrescente isto à imagem original:

cat /path/to/temp_image >> /path/to/rasperrypi.img

Redimensione o sistema de arquivos que fica no final do disco (geralmente esse é o que você deseja maior):

resize2fs -f /path/to/rasperrypi.img

Feito! Seu disco agora deve ser 5 GB maior!

Jivings
fonte
Parece perfeito, obrigado: vou testar isso hoje à noite.
DrAl
5
Eu apenas tentei isso e quando chego ao estágio resize2fs (depois de adicionar 1 GB ao arquivo), recebo "Número mágico ruim no superbloco ao tentar abrir 2012-12-16-wheezy-raspbian.img Não consegui ' t encontre um superbloco válido do sistema de arquivos ". Alguma sugestão sobre o que estou fazendo de errado?
DrAl
Parece-me que é um problema o fato de que estou tentando redimensionar a imagem inteira (o equivalente a / dev / sda) em vez da partição (o equivalente a / dev / sda2). No entanto, eu posso estar errado e tentei algumas outras coisas sem sucesso (como redimensionar a partição com o fdisk, que parece funcionar, mas não me ajuda a redimensionar o sistema de arquivos).
DrAl
3
Ok, eu encontrei a resposta para o último bit com um pouco de pesquisa: eu precisava criar um dispositivo de loop apontando para a partição na imagem. Eu fiz isso obtendo o setor inicial da segunda partição fdisk -l file.img(era 122880) e depois losetup --offset $((122880 * 512)) /dev/loop0 file.img. Eu poderia, então, usar resize2fsem /dev/loop0e arrumar com losetup -d /dev/loop0. Se você atualizar sua resposta para incluir isso, eu a marcarei como a resposta aceita. Obrigado por me apontar na direção certa.
DrAl
1
@DrAl Hey, eu tentei sua solução usando resize2fson /dev/loop0mas foi fico um kernel panic na inicialização dizendo que o tamanho superbloco e tamanho da partição não correspondem: The filesystem size (according to the superblock) is 483840 blocks The physical size of the device is 458240 blocksJá se deparou com algo assim?
GuySoft
4

Esta é uma síntese das respostas acima e de outros lugares que funcionaram para mim - faça backup da sua imagem caso você cometa um erro:

Primeiro, aumente o arquivo de imagem (aqui estamos adicionando 1 GB ao final):

truncate -s +1G ./image.img

Em seguida, mapeie toda a imagem como um dispositivo de loop, para que possamos cutucar a tabela de partição

sudo losetup /dev/loop0 ./image.img

Para referência futura, vamos despejá-lo:

sudo fdisk -l /dev/loop0

A saída se parece com:

Disk /dev/loop0: 2962 MB, 2962227200 bytes
255 heads, 63 sectors/track, 360 cylinders, total 5785600 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: 0x000c4661

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192      122879       57344    c  W95 FAT32 (LBA)
/dev/loop0p2          122880     5785599     2831360   83  Linux

Agora, refazemos a última partição excluindo-a e recriando-a no mesmo local de início, mesmo tipo, mas com local final diferente. Portanto, anote a coluna "Iniciar" da loop0p2 (partição 2 - a partição Linux) - nós a usaremos mais tarde - seu 122880 aqui.

sudo fdisk /dev/loop0

Digite o seguinte - eles são seguros para entrar - nada permanente acontece até que você leia minha explicação a seguir:

  1. p
  2. d
  3. 2
  4. n
  5. p
  6. 2
  7. 122880
  8. basta pressionar enter para aceitar o padrão
  9. p

Etapa 1 - imprima a tabela atual. Etapas 2-3 - exclua a partição 2, Etapas 4-8 - recrie a partição 2 com o novo ponto final (o padrão é o fim da imagem), Etapa 9 - imprima a nova tabela.

Supondo que sua tabela recém-impressa seja idêntica à tabela original, exceto pelos valores Final e Blocos (ou seja, o tamanho foi alterado) que você está pronto para confirmar.

Digite wpara confirmar sua alteração e digiteq para sair.

Você pode excluir esse dispositivo de loopback, criaremos outro para a segunda partição. Lembre-se do deslocamento inicial que você anotou e usou acima - nós o usaremos novamente:

sudo losetup -d /dev/loop0     # delete the old loop setup
sudo losetup -o $((122880*512)) /dev/loop0 ./image.img

Isso criará um novo mapeamento ao /dev/loop0apontar apenas para a partição 2 - pois a referência 512 é o tamanho do setor que você pode ver na primeira fdisksaída.

Agora redimensione a partição para preencher o espaço disponível:

sudo e2fsck -f /dev/loop0
sudo resize2fs /dev/loop0

Concluído - agora limpe:

sudo losetup -d /dev/loop0
Greg
fonte
obrigado ... as instruções acima não funcionaram para mim, mas isso funcionou. Recebi algum aviso ao escrever a tabela de partição: `` `Command (m for help): w A tabela de partição foi alterada. Chamando ioctl () para reler a tabela de partição. A leitura da tabela de partição falhou .: Argumento inválido O kernel ainda usa a tabela antiga. A nova tabela será usada na próxima reinicialização ou depois de executar o partprobe (8) ou o kpartx (8). `` Eu simplesmente o ignorei e isso foi bom.
StFS 18/03/19
Excelente! Você é o único que fez a resposta correta! Obrigado.
yushulx
3

Para quem tem o Oracle VM VirtualBox em execução, é bastante fácil.

Em uma máquina Windows, as coisas são as seguintes:

input.imgAqui está a imagem cujo tamanho deve ser reduzido e output.imga imagem final - neste exemplo definido como 7000 MB de tamanho.

ECHO "========================================================================="
ECHO "input.img => output.img"

ECHO "========================================================================="

DEL  input.vdi

DEL  output.vdi

DEL  output.img

ECHO "========================================================================="
"C:\Program Files\Oracle\VirtualBox\VBoxManage" convertfromraw input.img input.vdi -format VDI --variant Standard

ECHO =========================================================================
"C:\Program Files\Oracle\VirtualBox\VBoxManage" createhd --filename output.vdi --size 7000 --format VDI --variant Standard

ECHO =========================================================================
"C:\Program Files\Oracle\VirtualBox\VBoxManage" clonehd input.vdi output.vdi --existing

ECHO =========================================================================
"C:\Program Files\Oracle\VirtualBox\VBoxManage" clonehd output.vdi output.img --format RAW

Espero que isso ajude um pouco.

Markus
fonte
Obrigado por esta solução, muito astuto. É o único que pude encontrar que é gratuito e funciona perfeitamente no Windows. Eu tive alguns problemas com cartões de 16GB que não eram do mesmo tamanho e precisavam redimensionar minha imagem.
21717 Josh
Eu tenho erro de pânico no kernel. Kernel panic - not syncing: VFS: Unable to mount rootfs on unknown-block(179,2)
JPX
Observe que isso está truncando a imagem - você perderá dados se houver alguma marca de 7000 MB - os comandos não avisarão ou reclamarão.
Mike Redrobe
2

Isto é como redimensionar um arquivo de imagem bruto. Eu sei que parece estupidamente simplista, mas vai funcionar.

Crie uma imagem em branco, do tamanho que você deseja expandir o original (no meu exemplo eu uso 5 GB);

dd if=/dev/zero of=/path/to/temp_image bs=1 count=1 seek=5G

Acrescente isto à imagem original:

cat /path/to/temp_image >> /path/to/rpi.img

Em seguida, é redimensionar a partição e o sistema de arquivos. Primeiro, obtenha o deslocamento da partição;

fdisk -l /path/to/rpi.img

Resultados em uma tabela como esta:

Device    Boot   Start      End   Sectors   Size  Id  Type
rpi.img1          8192   122879    114688    56M   c  W95 FAT32 (LBA)
rpi.img2       1122880  8447999   8325120     4G  83  Linux

Observe o deslocamento inicial da segunda partição

losetup --offset $((122880 * 512)) /dev/loop0 /path/to/rpi.img
e2fsck -f /dev/loop0
resize2fs -f /dev/loop0

Por fim, desmonte / dev / loop

losetup -d /dev/loop0

Feito! Seu disco agora deve ser 5 GB maior!

Jonas Stumph Stevnsvig
fonte