Как сделать изображение (.img) из того, что находится на SD-карте (но такое же компактное, как оригинал)?

20

Я старался:

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

Он создает файл .img с 7,6 ГБ (размер карты, НО, что на карте имеет 700 МБ).

И:

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

создает файл .gz с 2,7 ГБ.

Оригинальный Raspbian ( Debian 7 (Wheezy)) с http://www.raspberrypi.org/downloads имеет 494,44 МБ.

Из того, что на SD-карте, как сделать изображение похожим по размеру?

(Я нахожусь на Ubuntu.)

mf_
источник
raspberrypi.stackexchange.com/questions/311/… это не помогло
mf_

Ответы:

18

В комментарии к RooTer вы упоминаете, что A) вы уменьшили первоначальный размер раздела gparted, но ddвсе равно копируете всю карту, и B) вы хотите включить оба раздела в образ.

Проблему «А» легко объяснить: вы все еще копируете всю карту, потому что это то, к чему /dev/mmcblk0относится. Отдельные разделы есть конечно /dev/mmcblk0p1и /dev/mmcblk0p2. Это сложность в проблеме «B», но вы не можете просто ddобъединить каждый раздел и объединить два файла из-за таблицы разделов, в начале /dev/mmcblk0 которой указываются начало и длина каждого раздела. Без этого изображение будет непригодным для использования.

Однако вы можете получить длину каждого раздела fdisk -lи использовать ее для определения некоторых параметров dd. Например:

> 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

Единицы «Начало» и «Конец» являются секторами, и обратите внимание на размер сектора, 512 байт. Для /dev/mmcblk0p2, 26746879 (последний сектор) - 122880 (первый сектор) = 26623999/2 (для 2 секторов на кБ) / 1024 (КБ на МБ) / 1024 (МБ на ГБ) = 12,69, которые я увеличил с помощью gparted до 12 ГБ, так что это выглядит правильно (на самом деле я должен использовать 1000, а не 1024 в качестве делителя с хранилищем, которое работает до 13,31 ГБ, но я подозреваю, что gparted и некоторые другие инструменты также используют 1024).

Итак, первое, что вы хотите проверить, это то, что ваш второй раздел действительно меньше установленного вами размера. Далее просто используйте эти числа с dd; для меня это было бы:

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

У меня там есть дополнительный сектор, чтобы избежать какого-либо непонимания того, как ddработает. Есть простой способ проверить, сработало ли это:

> 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

Обратите внимание, что здесь есть небольшое расхождение: сектора «Начало» и «Конец» соответствуют исходной таблице разделов, но общий размер в верхней части статистики составляет всего 102 МБ! Это потому, что я на самом деле использовал count=200000в качестве параметра, ddпотому что я действительно не хотел беспокоиться о копии 12 ГБ (обратите внимание также «всего 200000 секторов»). Причина, по которой таблица внизу не отражает это, заключается в том, что fdisk получает свою информацию из данных раздела, скопированных дословно в начале изображения с начала SD-карты, что, как я упоминал во втором абзаце, является жизненно важным поддерживать. Если бы я (правильно) скопировал все остальное, числа были бы одинаковыми, и изображение было бы жизнеспособным.

Дайте это попробовать. :)

Златовласка
источник
В OSX fdisk не распечатывает размер сектора в байтах. Вместо этого предлагается «геометрия: 966/255/63 [15523840 секторов]», представляющая цилиндры / головки / сектора. Какие значения bs и count следует использовать в этом случае?
Артур Хеберт
@ArthurHebert: Всего байт / общее количество секторов. Например, в первом случае выше это будет 16138633216/31520768 = 512, во втором 102400000/200000 = 512.
Златовласка
1
Вы можете использовать fdisk -l <device>и тот, который должен распечатать таблицу, не переходя в интерактивный режим.
Берто
5

Я предполагаю, что проблема заключается в когда-то используемых секторах, в которых все еще есть грязь. Как только файл удален, из файловой системы удаляются только метаданные, а не сами данные, что оставляет некоторые случайные единичные нули вместо того, чтобы просто сжимать блоки, содержащие только ноль.

Простое решение, но требует перезаписи всего свободного места на карте. Помните, что время жизни SD-карты ограничено количеством перезаписей, поэтому этот метод не является предпочтительным.

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

Более сложное решение, так как вам нужно установить zerofree на другой компьютер, который не будет использовать эту SD-карту в то время.

zerofree /dev/mmcblk0p2

Подробнее читайте на http://intgat.tigress.co.uk/rmy/uml/index.html

Следует помнить, что, выполнив команду dd of / dev / mmcblk0, вы копируете все устройство, даже если разделы меньше. Если вы использовали raspi-config для расширения основного раздела перед выполнением одного из указанных выше способов, у вас все будет хорошо.

PS Если вы не возражаете против изменения формата файла изображения, вы можете использовать partimage, который для известных файловых систем пропускает освобожденные блоки, даже если в них все еще есть грязь. Опять же, partimage лучше всего использовать, когда файловая система не смонтирована, чтобы избежать повреждения резервной копии. Вы, вероятно, могли бы избежать повторного подключения только для чтения, но я оставлю это на ваше усмотрение.

болельщик
источник
как часть моего квеста, пытаясь добиться этого, я использовал gparted, чтобы уменьшить раздел sdcard, чтобы разместить только те данные, которые у меня есть, затем я попытался dd ing, и результаты - тот же файл 7.6 ГБ, partimage не может сохранить 2 раздела (/ загрузиться + /) в 1 изображение
mf_
может быть, я не достаточно ясно дал понять - это должно иметь значение, когда вы сжимаете его, как вы уже пробовали с помощью gzip.
RooTer
заполнение карты таким образом вызовет целую кучу циклов записи и сократит срок службы карты. попробуйтеdd bs=4M if=/dev/zero of=/root/junk
nc4pk
@ tapped-out thx, отредактировано;)
RooTer
4

Краткий ответ - используйте 2 ГБ SD-карту.

Длинный ответ, ddпонятия не имеет, где заканчиваются «хорошие» данные, вы должны как-то рассказать.

Есть два способа, самый простой - использовать 2 ГБ SD-карту, которая автоматически прекратит копирование за пределами 2 ГБ и приведет к сжатию файла размером 500 МБ по вашему желанию.

Другой способ, более сложный и сложный, состоит в том, чтобы вычислить правильный размер данных из таблицы разделов и указать этот правильный размер в качестве параметров для ddкоманды. Для этой цели вы можете использовать параметры bs=XXX(размер блока) и count=XXX(количество блоков). Например, вы можете указать bs=10Mразмер блока 10 МБ (который определенно сделает копирование намного быстрее по сравнению с размером блока 4 КБ, который вы используете в своих командах) и count=200скопировать 10 МБ * 200 = 2000 МБ (2 ГБ). Возможно, вам придется настроить размер блока и количество блоков в соответствии со схемой разбиения вашей SD-карты .

Lenik
источник
1
Предоставление ddопределенного размера никогда не будет работать. Это предполагает, что все фактические данные в файловой системе аккуратно расположены в начале устройства, поэтому, если у вас 2 ГБ на 8 ГБ разделе, вам просто нужно скопировать первые 2 ГБ. Это ЛОЖЬ. Эти 2 ГБ данных будут разбросаны по всему пространству, особенно на современных SD-картах, которые не используют блоки дважды, пока все доступные блоки не будут использованы хотя бы один раз (это называется выравниванием износа и продлевает срок службы карты).
Златовласка
@goldilocks, что если я изменю размер SD-карты, чтобы сжать все разделы до максимально возможного размера (только данные)?
mf_
@goldilocks, пожалуйста, прочитайте вопрос и ответ более внимательно, я говорю о разделе 2 ГБ на SD-карте 8 ГБ, а не о данных 2 ГБ на разделе 8 ГБ, как вам как-то подсказало ваше дикое воображение.
lenik
1
lenik: Да, я немного ошеломлен, я истолковал вас таким образом, все извинения - к сожалению, я не могу отменить свое понижение, если вы не отредактируете сообщение: / хотя я все еще не думаю, что этот ответ особенно полезен (без обид - - потому что это не просто раздел , инструкции о том, как это сделать, опять же, бесполезны), но я сделаю это. @ mf_ Да, это выполнимо (вы читали мой ответ? Это сработает ...)
Златовласка
@goldilocks Я отредактировал ответ. Не знаю, почему это бесполезно, особенно если вы дали точно такой же ответ, только с более подробной информацией.
lenik
1

dd - copy and convertэто не тот инструмент, который вам нужен. Это низкоуровневый инструмент для секторного копирования (и преобразования), который отлично подходит для копирования загрузочных секторов, форматирования устройств и всевозможных низкоуровневых задач. При использовании ddвы копируете посекторное изображение, даже если оно не включено в структуру файловой системы.

Образы, предоставленные фондом Raspberry Pi, представляют собой специально скомпилированные образы с установочными сценариями, разархивирующими двоичными файлами и начальной установкой, после чего вам все равно нужно получать обновления из Интернета - что является целенаправленной, но довольно сложной задачей, чтобы заставить его работать таким образом.

Одним из популярных решений, позволяющих избежать копирования пустых секторов, является использование системы копирования на уровне файлов - и CloneZilla является автономной, загружаемой с компакт-диска, аналогичной, ye olde Norton Ghostно clonezilla поддерживает файловые системы Linux (и более). Таким образом, он будет копировать только используемые файлы и создавать контейнер только из этих файлов. Уменьшает размер значительно!

Петр Кула
источник
1

У меня был точно такой же вопрос, и я хотел простой в использовании инструмент. После поиска и не нахождения одного я написал mkimg.sh . Я обрисовал в общих чертах процесс, который я использовал в: /raspberrypi//a/37899/32585

Берто
источник