¿Cómo hacer una imagen (.img) a partir de lo que hay en la tarjeta SD (pero tan compacta como la original)?

20

Lo intenté:

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

Crea un archivo .img con 7,6 GB (tamaño de la tarjeta, PERO lo que hay en la tarjeta tiene 700 MB).

Y:

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

crea un archivo .gz con 2.7 GB.

El Raspbian original ( Debian 7 (Wheezy)) de http://www.raspberrypi.org/downloads tiene 494.44 MiB.

De lo que hay en la tarjeta SD, ¿cómo puedo hacer una imagen de tamaño similar?

(Estoy en Ubuntu).

mf_
fuente

Respuestas:

18

Menciona en un comentario a RooTer que A) ha reducido el tamaño inicial de la partición gparted, pero ddaún copia toda la tarjeta, y B) que desea incluir ambas particiones en la imagen.

El problema "A" es fácil de explicar: todavía está copiando toda la tarjeta porque a eso se /dev/mmcblk0refiere. Las particiones individuales son, por supuesto, /dev/mmcblk0p1y /dev/mmcblk0p2. Esta es la complicación en el problema "B", pero no puede simplemente ddcada partición y concatenar los dos archivos juntos, debido a que la tabla de partición al principio de la /dev/mmcblk0 cual indexa el comienzo y la longitud de cada partición. Sin eso, la imagen quedará inutilizable.

Sin embargo, puede obtener la longitud de cada partición fdisk -ly usarla para determinar algunos parámetros dd. Por ejemplo:

> 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

Las unidades "Inicio" y "Fin" son sectores, y observe que el tamaño del sector es de 512 bytes. Para /dev/mmcblk0p2, 26746879 (el último sector) - 122880 (el primer sector) = 26623999/2 (para 2 sectores por kB) / 1024 (kB por MB) / 1024 (MB por GB) = 12.69, que creció la partición usando gparted a 12 GB, por lo que esto parece correcto (realmente debería usar 1000 y no 1024 como divisor con almacenamiento, lo que equivale a 13.31 GB, pero sospecho que gparted y algunas otras herramientas también usan 1024).

Entonces, lo primero que desea verificar es que su segunda partición es realmente el tamaño más pequeño en el que la configuró. Luego, solo usa esos números con dd; para mi seria:

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

Tengo un sector adicional allí para evitar cualquier tipo de error por un malentendido de cómo ddfunciona. Hay una manera simple de verificar si esto funcionó:

> 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 hay una pequeña discrepancia aquí: los sectores "Inicio" y "Fin" coinciden con la tabla de partición original, ¡pero el tamaño total en las estadísticas superiores es de solo 102 MB! Esto se debe a que realmente lo utilicé count=200000como parámetro ddporque realmente no quería molestarme con una copia de 12 GB (observe también "total de 200000 sectores"). La razón por la que la tabla en la parte inferior no refleja esto es porque fdisk está obteniendo su información de los datos de la partición copiados literalmente al comienzo de la imagen desde el comienzo de la tarjeta SD, lo cual, como mencioné en el segundo párrafo, es vital mantener. Si hubiera copiado (correctamente) el resto, los números serían copacetic y la imagen sería viable.

Pruébalo :)

Ricitos de oro
fuente
En OSX, fdisk no imprime claramente el tamaño del sector en bytes. En su lugar, ofrece "geometría: 966/255/63 [15523840 sectores]" que representa cilindros / culatas / sectores. ¿Qué valores de bs y count deben usarse en este caso?
Arthur Hebert
@ArthurHebert: bytes totales / sectores totales. Por ejemplo, en el primer caso anterior sería 16138633216/31520768 = 512, en el segundo 102400000/200000 = 512.
goldilocks
1
Puede usar fdisk -l <device>y eso debería imprimir la tabla sin entrar en modo interactivo.
berto
5

Supongo que el problema radica en sectores que alguna vez fueron usados ​​y que todavía tienen suciedad. Una vez que se elimina el archivo, solo se eliminan los metadatos del sistema de archivos, no los datos en sí mismos, lo que deja algunos ceros aleatorios en lugar de bloques fáciles de comprimir cero.

Solución fácil, pero requiere reescribir todo el espacio libre en la tarjeta. Recuerde que la vida útil de la tarjeta SD está limitada por el número de reescrituras, por lo que este no es el método preferido.

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

Solución más complicada, ya que necesita instalar zerofree en otra computadora que no utilizará esa tarjeta SD en ese momento.

zerofree /dev/mmcblk0p2

Para más información, lea http://intgat.tigress.co.uk/rmy/uml/index.html

Lo que debe recordar es que al hacer dd of / dev / mmcblk0 copia todo el dispositivo, incluso si las particiones son más pequeñas. Si utilizó raspi-config para expandir la partición principal antes de realizar uno de los métodos anteriores, estará bien.

PD: si no le importa cambiar el formato del archivo de imagen, puede usar imágenes de partición que para los sistemas de archivos conocidos omiten los bloques liberados incluso si todavía tienen algo de suciedad. Nuevamente, es mejor usar partimage cuando el sistema de archivos no está montado para evitar la corrupción de la copia de seguridad. Probablemente podría salirse con el montaje de solo lectura, pero lo dejaré a su discreción.

Hincha
fuente
como parte de mi búsqueda en tratar de conseguir este hecho, he utilizado GParted para reducir la partición sdcard de alojar sólo los datos que tengo, a continuación, he intentado dd ING y los resultados son el mismo archivo 7.6GB, no puede partimage ahorro 2 particiones (/ arranque + /) en 1 imagen
mf_
tal vez no lo dejé lo suficientemente claro: debería hacer una diferencia cuando lo comprimes, como lo has intentado con gzip antes.
RooTer
llenar la tarjeta de esta manera provocará un montón de ciclos de escritura y acortará la vida útil de la tarjeta. trydd bs=4M if=/dev/zero of=/root/junk
nc4pk
@ thx
extraído
4

Respuesta corta: use una tarjeta SD de 2GB.

Respuesta larga, ddno tiene idea de dónde terminan los datos "buenos", hay que decirlo de alguna manera.

Hay dos formas, la más fácil es usar una tarjeta SD de 2GB, que detendrá automáticamente la copia más allá de 2GB y dará como resultado un archivo comprimido de 500MB como desee.

La otra forma, una más complicada, es calcular el tamaño de datos correcto de su tabla de particiones y especificar este tamaño correcto como parámetros para ddordenar. Puede usar los parámetros bs=XXX(tamaño de bloque) y count=XXX(recuento de bloques) para ese propósito. Por ejemplo, puede especificar bs=10Mun tamaño de bloque de 10 MB (eso definitivamente haría que la copia sea mucho más rápida en comparación con el tamaño de bloque de 4k que usa en sus comandos) y count=200copiar 10 MB * 200 = 2000 MB (2 GB). Es posible que deba ajustar el tamaño y el recuento de bloques de acuerdo con el esquema de partición de su tarjeta SD .

lenik
fuente
1
Darle ddun tamaño específico NUNCA funcionará. Eso supone que todos los datos reales en el sistema de archivos están ordenados al principio del dispositivo, por lo que si tiene 2 GB en una partición de 8 GB, solo necesita copiar los primeros 2 GB. Esto es falso. Esos 2 GB de datos se distribuirán por todo el espacio, especialmente en las tarjetas SD modernas que no reutilizan bloques dos veces hasta que todos los bloques disponibles se hayan utilizado al menos una vez (esto se denomina nivelación de desgaste y prolonga la vida útil de la tarjeta).
Ricitos de oro
@goldilocks, ¿qué pasa si cambio el tamaño de la tarjeta sd para reducir todas las particiones al máximo tamaño posible (solo datos)?
mf_
@goldilocks, por favor, lea la pregunta y la respuesta con más cuidado, estoy hablando de una partición de 2GB en una tarjeta SD de 8GB, no de datos de 2GB en una partición de 8GB, como su imaginación salvaje le dijo de alguna manera.
lenik
1
lenik: Sí, estoy un poco aturdido. Te interpreté de esa manera, disculpas, lamentablemente no puedo revertir mi voto negativo a menos que edites la publicación: / aunque todavía no creo que esta respuesta sea particularmente útil (sin ofender - - porque esto no es simplemente hacer una partición , las instrucciones sobre cómo hacerlo no son útiles), pero lo haré. @mf_ Sí, eso es factible (¿leíste mi respuesta? Funcionará ...)
goldilocks
@goldilocks He editado la respuesta. No sé por qué no es útil, especialmente cuando dio exactamente la misma respuesta, solo que con más detalles.
lenik
1

dd - copy and convertNo es la herramienta adecuada para hacer el trabajo que ha solicitado. Es una herramienta de copia (y conversión) sector por sector de bajo nivel, que es excelente para copiar sectores de arranque, formatear dispositivos y todo tipo de tareas de bajo nivel. Cuando lo usa dd, está copiando sector por sector a la imagen, incluso si no está incluido en la Estructura del sistema de archivos.

Las imágenes proporcionadas por la fundación Raspberry Pi son imágenes especialmente compiladas con scripts de instalación, binarios de descompresión y configuración inicial, después de lo cual debe obtener actualizaciones de Internet de todos modos, lo cual es todo deliberado pero una tarea bastante difícil para que funcione de esta manera.

Una solución popular para evitar copiar sectores vacíos es usar un sistema de copia de nivel de archivo , y CloneZilla es independiente, arrancable desde un CD, similar ye olde Norton Ghostpero clonezilla es compatible con los sistemas de archivos Linux (y más). Por lo tanto, solo copiará los archivos que estén en uso y creará un contenedor solo a partir de esos archivos. Reduce el tamaño significativamente!

Piotr Kula
fuente
1

Tenía la misma pregunta exacta y quería una herramienta fácil de usar. Después de buscar y no encontrar uno, escribí mkimg.sh . Describo el proceso que utilicé en: /raspberrypi//a/37899/32585

berto
fuente