¿Cómo cambiar el tamaño de un archivo de imagen antes de escribir en la tarjeta SD?

13

He estado tratando de crear una nueva imagen de Raspbian con un kernel diferente (con soporte CAN) y con Python 3.3 instalado. En lugar de hacer todo esto en la Raspberry Pi, pensé que sería interesante hacerlo en la computadora (siguiendo estas instrucciones ). Sin embargo, una vez que tuve la imagen montada y lista para funcionar, rápidamente me quedé sin espacio en disco. Supongo que esto se debe a que el tamaño de la imagen es lo suficientemente grande con la expectativa de que el usuario cambie el tamaño del sistema de archivos una vez que se haya escrito en una tarjeta SD.

¿Es posible cambiar el tamaño de la imagen y el sistema de archivos antes de escribirlo en la tarjeta SD para que pueda hacer más personalización sin quedarse sin espacio?

DrAl
fuente
Esta pregunta probablemente te ayudará.
Jivings
1
@Jivings: todas estas respuestas describen cómo cambiar el tamaño de la imagen después de que se haya escrito en la tarjeta SD. Yo se como hacer eso; Estoy interesado en cómo cambiar el tamaño de la imagen antes de escribirla en la tarjeta SD.
DrAl

Respuestas:

7

Así es como cambiar el tamaño de un archivo de imagen sin formato. Sé que suena estúpidamente simplista, pero funcionará.

Cree una imagen en blanco, del tamaño que desea expandir el original (en mi ejemplo uso 5GB);

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

Agregue esto a la imagen original:

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

Cambie el tamaño del sistema de archivos que vive al final del disco (generalmente este es el que desea más grande):

resize2fs -f /path/to/rasperrypi.img

¡Hecho! ¡Tu disco ahora debería ser 5GB más grande!

Jivings
fuente
Eso suena perfecto, gracias: probaré esto esta noche.
DrAl
55
Acabo de intentar esto y cuando llego a la etapa resize2fs (después de agregar 1GB al archivo), obtengo "Número mágico incorrecto en superbloque al intentar abrir 2012-12-16-wheezy-raspbian.img couldn ' t encuentra un superbloque de sistema de archivos válido ". ¿Alguna sugerencia sobre lo que estoy haciendo mal?
DrAl
Me parece que es un problema con el hecho de que estoy tratando de cambiar el tamaño de la imagen completa (el equivalente de / dev / sda) en lugar de la partición (el equivalente de / dev / sda2). Sin embargo, podría estar equivocado y he intentado algunas otras cosas sin éxito (como cambiar el tamaño de la partición con fdisk, que parece funcionar pero no me ayuda a cambiar el tamaño del sistema de archivos).
DrAl
3
De acuerdo, encontré la respuesta al último bit con un poco de búsqueda en Google: necesitaba crear un dispositivo de bucle que apuntara a la partición en la imagen. Hice esto obteniendo el sector de inicio de la segunda partición de fdisk -l file.img(era 122880) y luego losetup --offset $((122880 * 512)) /dev/loop0 file.img. Entonces podría utilizar resize2fsen /dev/loop0y poner en orden con losetup -d /dev/loop0. Si actualiza su respuesta para incluir esto, lo marcaré como la respuesta aceptada. Gracias por señalarme en la dirección correcta.
DrAl
1
@DrAl Hey, he intentado utilizar su solución resize2fsen /dev/loop0, pero se habían consigo un pánico del kernel en el arranque diciendo que el tamaño del superbloque y tamaño de la partición no coinciden: The filesystem size (according to the superblock) is 483840 blocks The physical size of the device is 458240 blocks¿Se ha encontrado algo como esto?
GuySoft
4

Esta es una síntesis de las respuestas anteriores y en otros lugares que funcionó para mí: haga una copia de seguridad de su imagen en caso de que cometa un error:

Primero, haga que el archivo de imagen sea más grande (aquí estamos agregando 1GB al final):

truncate -s +1G ./image.img

A continuación, asigne la imagen completa como un dispositivo de bucle para que podamos tocar la tabla de particiones

sudo losetup /dev/loop0 ./image.img

Para futuras referencias, volquémoslo:

sudo fdisk -l /dev/loop0

La salida se ve así:

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

Ahora rehaceremos la última partición eliminándola, luego volviendo a crearla en la misma ubicación de inicio, el mismo tipo pero diferente ubicación final. Así que tome nota de la columna "Inicio" para loop0p2 (partición 2 - la partición de Linux) - la usaremos más tarde - aquí es 122880.

sudo fdisk /dev/loop0

Ingrese lo siguiente (es seguro ingresar), no ocurre nada permanente hasta que haya leído mi explicación a continuación:

  1. p
  2. d
  3. 2
  4. n
  5. p
  6. 2
  7. 122880
  8. simplemente presione enter para aceptar el valor predeterminado
  9. p

Paso 1: imprime la tabla actual. Pasos 2-3: elimine la partición 2, Pasos 4-8: vuelva a crear la partición 2 con un nuevo punto final (el valor predeterminado es el final de la imagen), Paso 9: imprima la nueva tabla.

Suponiendo que su tabla recién impresa es idéntica a la tabla original, excepto por el valor Final y el valor Bloques (es decir, el tamaño ha cambiado) que está listo para confirmar.

Ingrese wpara confirmar su cambio, luego ingrese qpara salir.

Puede eliminar ese dispositivo de bucle invertido, haremos otro para la segunda partición. Recuerde el desplazamiento de inicio que anotó y usó anteriormente; lo usaremos nuevamente:

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

Eso creará un nuevo mapeo al /dev/loop0apuntar solo a la partición 2: para la referencia 512 es el tamaño de sector que puede ver en la primera fdisksalida.

Ahora cambie el tamaño de la partición para llenar el espacio disponible:

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

Listo - ahora limpia:

sudo losetup -d /dev/loop0
Greg
fuente
gracias ... las instrucciones anteriores no funcionaron para mí, pero esto sí. Recibí alguna advertencia al escribir la tabla de particiones: `` `Comando (m para ayuda): w La tabla de particiones ha sido alterada. Llamando a ioctl () para volver a leer la tabla de particiones. Error al volver a leer la tabla de particiones .: Argumento no válido El núcleo todavía usa la tabla anterior. La nueva tabla se usará en el próximo reinicio o después de ejecutar partprobe (8) o kpartx (8). `` Simplemente lo ignoré y eso estuvo bien.
StFS
¡Excelente! ¡Eres el único que dio la respuesta correcta! Gracias.
yushulx
3

Para aquellos que tienen Oracle VM VirtualBox ejecutándose, es bastante fácil.

En una máquina Windows, las cosas son las siguientes:

input.imgAquí está la imagen cuyo tamaño debe reducirse y output.imges la imagen final, en este ejemplo definida como 7000 MB de gran tamaño.

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 esto ayude un poco.

Markus
fuente
Gracias por esta solución, muy astuto. Es el único que he podido encontrar que es gratuito y funciona perfectamente en Windows. Tuve algunos problemas con las tarjetas de 16GB que no tenían el mismo tamaño y que necesitaba cambiar el tamaño de mi imagen.
Josh
Tengo un error de kernel panic. Kernel panic - not syncing: VFS: Unable to mount rootfs on unknown-block(179,2)
JPX
Tenga en cuenta que esto está truncando la imagen: perderá datos si supera la marca de 7000 MB; los comandos no avisarán ni se quejarán.
Mike Redrobe
2

Así es como cambiar el tamaño de un archivo de imagen sin formato. Sé que suena estúpidamente simplista, pero funcionará.

Cree una imagen en blanco, del tamaño que desea expandir el original (en mi ejemplo uso 5GB);

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

Agregue esto a la imagen original:

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

Lo siguiente es cambiar el tamaño de la partición y el sistema de archivos. Primero, obtenga el desplazamiento de la partición;

fdisk -l /path/to/rpi.img

Resultados en una tabla 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

Tenga en cuenta el desplazamiento inicial de la segunda partición

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

Por último desmontar / dev / loop

losetup -d /dev/loop0

¡Hecho! ¡Tu disco ahora debería ser 5GB más grande!

Jonas Stumph Stevnsvig
fuente