Jak zrobić obraz (.img) z zawartości karty SD (ale tak kompaktowej jak oryginalna)?

20

Próbowałem:

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

Tworzy plik .img z 7,6 GB (rozmiar karty, ALE to, co jest na karcie, ma 700 MB).

I:

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

tworzy plik .gz o 2,7 GB.

Oryginalny Raspbian ( Debian 7 (Wheezy)) z http://www.raspberrypi.org/downloads ma 494,44 MiB.

Z tego, co jest na karcie SD, jak mogę zrobić obraz o podobnym rozmiarze?

(Jestem na Ubuntu.)

MF_
źródło

Odpowiedzi:

18

W komentarzu do RooTer wspominasz, że A) zmniejszyłeś początkowy rozmiar partycji gparted, ale ddnadal kopiujesz całą kartę, i B), że chcesz dołączyć obie partycje do obrazu.

Zagadnienie „A” jest łatwe do wyjaśnienia: nadal kopiujesz całą kartę, ponieważ właśnie o to chodzi /dev/mmcblk0. Poszczególne partycje są oczywiście /dev/mmcblk0p1i /dev/mmcblk0p2. Jest to komplikacja w numerze „B”, ale nie można po prostu ddkażdej partycji i połączyć dwóch plików razem, ponieważ tabela partycji na początku /dev/mmcblk0 indeksuje początek i długość każdej partycji. Bez tego obraz będzie bezużyteczny.

Możesz jednak pobrać długość każdej partycji fdisk -li użyć jej do określenia niektórych parametrów dd. Na przykład:

> 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

Jednostki „Start” i „Koniec” są sektorami i zauważają, że podany jest rozmiar sektora, 512 bajtów. Dla /dev/mmcblk0p2, 26746879 (ostatni sektor) - 122880 (pierwszy sektor) = 26623999/2 (dla 2 sektorów na kB) / 1024 (kB na MB) / 1024 (MB na GB) = 12,69, które powiększyłem partycję używając gparted do 12 GB, więc wygląda to poprawnie (naprawdę powinienem używać 1000, a nie 1024 jako dzielnika z pamięcią, który działa do 13,31 GB, ale podejrzewam, że gpart i niektóre inne narzędzia również używają 1024).

Pierwszą rzeczą, którą chcesz sprawdzić, jest to, że twoja druga partycja ma naprawdę mniejszy rozmiar, na jaki ją ustawiłeś. Następnie użyj tych liczb z dd; dla mnie byłoby to:

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

Mam tam dodatkowy sektor, aby uniknąć jakiegokolwiek nieporozumienia przez jedno nieporozumienie dotyczące sposobu dddziałania. Istnieje prosty sposób sprawdzenia, czy to zadziałało:

> 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

Zauważ, że jest tu trochę rozbieżności: sektory „Start” i „End” pasują do oryginalnej tabeli partycji, ale całkowity rozmiar w górnej części statystyk to tylko 102 MB! To dlatego, że faktycznie użyłem count=200000jako parametru, ddponieważ tak naprawdę nie chciałem zawracać sobie głowy kopią 12 GB (zauważ także „ogółem 200 000 sektorów”). Tabela u dołu tego nie odzwierciedla, ponieważ fdisk pobiera swoje informacje z danych partycji skopiowanych dosłownie na początku obrazu od początku karty SD, co, jak wspomniałem w drugim akapicie, jest niezbędne utrzymać. Gdybym (właściwie) skopiował resztę, liczby byłyby kopacetyczne, a obraz byłby wykonalny.

Spróbuj. :)

Złotowłosa
źródło
W OSX fdisk nie drukuje wyraźnie wielkości sektora w bajtach. Zamiast tego oferuje „geometrię: 966/255/63 [15523840 sektorów]” reprezentującą cylindry / głowice / sektory. Jakie wartości bs i count należy w tym przypadku zastosować?
Arthur Hebert
@ArthurHebert: Całkowita liczba bajtów / całkowita liczba sektorów. Np. W pierwszym powyższym przypadku będzie to 16138633216/31520768 = 512, w drugim 102400000/200000 = 512.
złotowłosy
1
Możesz użyć fdisk -l <device>i to powinno wydrukować tabelę bez przechodzenia w tryb interaktywny.
berto
5

Domyślam się, że problem tkwi w kiedyś używanych sektorach, które wciąż mają w sobie brud. Po usunięciu pliku z systemu plików usuwane są tylko metadane, a nie same dane, pozostawiając w ten sposób losowe cyfry zera zamiast łatwych do kompresji bloków zera.

Proste rozwiązanie, ale wymaga przepisania całej wolnej przestrzeni na karcie. Pamiętaj, że żywotność karty SD jest ograniczona liczbą przeróbek, więc nie jest to preferowana metoda.

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

Bardziej zaangażowane rozwiązanie, ponieważ musisz zainstalować zeroofree na innym komputerze, który nie będzie korzystał z tej karty SD w tym czasie.

zerofree /dev/mmcblk0p2

Więcej informacji można znaleźć na stronie http://intgat.tigress.co.uk/rmy/uml/index.html

Musisz pamiętać, że robiąc dd z / dev / mmcblk0 kopiujesz całe urządzenie, nawet jeśli partycje są mniejsze. Jeśli użyłeś raspi-config do rozszerzenia partycji głównej przed wykonaniem jednej z powyższych metod, wszystko będzie dobrze.

PS Jeśli nie masz nic przeciwko zmianie formatu pliku obrazu, możesz użyć partimage, który dla znanych systemów plików pomija zwolnione bloki, nawet jeśli nadal mają w sobie trochę brudu. Ponownie najlepiej jest używać partimage, gdy system plików nie jest zamontowany, aby uniknąć uszkodzenia kopii zapasowej. Prawdopodobnie mógłbyś uniknąć ponownego zamontowania go tylko do odczytu, ale pozostawiam to do uznania.

Kibic
źródło
jako część moich poszukiwań na próby, aby to zrobić, użyłem GParted, aby zmniejszyć partycję sdcard do acomodate tylko dane mam, a potem próbowałem dd ing i wyniki są takie same plik 7.6GB, partimage cant save 2 partycje (/ boot + /) do 1 obrazu
mf_
może nie wyjaśniłem tego wystarczająco jasno - powinno to mieć znaczenie, kiedy go skompresujesz, tak jak próbowałeś z gzip.
RooTer,
wypełnienie karty w ten sposób spowoduje cały szereg cykli zapisu i skróci żywotność karty. trydd bs=4M if=/dev/zero of=/root/junk
nc4pk
@ tapped-out thx, zredagowane;)
RooTer
4

Krótka odpowiedź - użyj karty SD 2 GB.

Długa odpowiedź, ddnie ma pojęcia, gdzie kończą się „dobre” dane, trzeba to jakoś powiedzieć.

Są dwa sposoby, najłatwiejsze jest użycie karty SD o pojemności 2 GB, która automatycznie przerwie kopiowanie powyżej 2 GB i spowoduje skompresowanie 500 MB pliku, jak chcesz.

Drugi sposób, bardziej skomplikowany, dotyczy obliczenia prawidłowego rozmiaru danych z tabeli partycji i określenia tego prawidłowego rozmiaru jako parametrów do ddpolecenia. W tym celu można użyć parametrów bs=XXX(rozmiar bloku) i count=XXX(liczba bloków). Na przykład możesz określić bs=10Mrozmiar bloku 10 MB (co zdecydowanie przyspieszyłoby kopiowanie znacznie szybciej niż rozmiar bloku 4k używany w poleceniach) i count=200skopiować 10 MB * 200 = 2000 MB (2 GB). Konieczne może być dostosowanie rozmiaru i liczby bloków zgodnie ze schematem partycji karty SD .

Lenik
źródło
1
Podanie ddokreślonego rozmiaru NIGDY NIGDY nie zadziała. Zakłada się, że wszystkie rzeczywiste dane w systemie plików są uporządkowane na początku urządzenia, więc jeśli masz 2 GB na partycji 8 GB, wystarczy skopiować pierwsze 2 GB. To nieprawda. Te 2 GB danych zostaną rozrzucone po całej przestrzeni, szczególnie na nowoczesnych kartach SD, które nie wykorzystują bloków dwa razy, dopóki wszystkie dostępne bloki nie zostaną użyte co najmniej raz (jest to nazywane wyrównywaniem zużycia i wydłuża żywotność karty).
goldilocks
@Goldilocks Co zrobić, jeśli zmienię rozmiar karty SD, aby zmniejszyć wszystkie partycje do maksymalnego możliwego rozmiaru (tylko dane)?
mf_
@Goldilocks, przeczytaj uważniej pytanie i odpowiedź, mówię o partycji 2 GB na karcie SD o pojemności 8 GB, a nie o danych 2 GB na partycji 8 GB, jak to w jakiś sposób powiedziała twoja dzika wyobraźnia.
lenik
1
lenik: Tak, jestem trochę oszołomiony. Zinterpretowałem cię w ten sposób, wszystkie przeprosiny - niestety nie mogę cofnąć mojego zdania, chyba że edytujesz post: / chociaż nadal nie sądzę, aby ta odpowiedź była szczególnie przydatna (bez obrazy - - ponieważ nie jest to po prostu partycja , instrukcje, jak to zrobić, znów nie są przydatne), ale zrobię to. @mf_ Tak, to wykonalne (czy przeczytałeś moją odpowiedź? To zadziała ...)
goldilocks
@Goldilocks Zredagowałem odpowiedź. Nie wiem, dlaczego nie jest to przydatne, zwłaszcza gdy udzieliłeś dokładnie tej samej odpowiedzi, tylko z dodatkowymi szczegółami.
lenik,
1

dd - copy and convertnie jest odpowiednim narzędziem do wykonania żądanej pracy. Jest to narzędzie do kopiowania (i konwertowania) sektor po sektorze, które doskonale kopiuje sektory rozruchowe, formatuje urządzenia i wszelkiego rodzaju zadania niskiego poziomu. Podczas korzystania ddkopiujesz sektor po sektorze do obrazu, nawet jeśli nie jest on uwzględniony w strukturze systemu plików.

Obrazy dostarczone przez fundację Raspberry Pi to specjalnie skompilowane obrazy ze skryptami instalacyjnymi, rozpakowywaniem plików binarnych i wstępną konfiguracją, po których i tak musisz otrzymywać aktualizacje z Internetu - co jest celowe, ale dość trudne, aby działało w ten sposób.

Jednym z popularnych rozwiązań pozwalających uniknąć kopiowania pustych sektorów jest użycie systemu kopiowania na poziomie plików - a CloneZilla jest samodzielna, można ją uruchomić z płyty CD, podobnie jak ye olde Norton Ghostclonezilla obsługuje systemy plików Linux (i więcej). Dlatego kopiuje tylko używane pliki i tworzy kontener tylko z tych plików. Znacząco zmniejsza rozmiar!

Piotr Kula
źródło
1

Miałem to samo dokładne pytanie i chciałem łatwego w użyciu narzędzia. Po przeszukaniu i nie znalezieniu jednego napisałem mkimg.sh . Zarysuję proces, którego użyłem na: /raspberrypi//a/37899/32585

berto
źródło