如何使用SD卡中的图像制作图像(.img)(但与原始图像一样紧凑)?


20

我试过了:

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

它会创建一个7.6 GB的.img文件(卡大小,但卡上有700 MB)。

和:

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

创建一个2.7 GB的.gz文件。

来自http://www.raspberrypi.org/downloads的原始Raspbian(Debian 7(Wheezy))具有494.44 MiB。

从SD卡上的图像中,如何制作尺寸相似的图像?

(我在Ubuntu上。)


Answers:


18

您在对RooTer的评论中提到:A)您已使用减小了初始分区的大小gparted,但dd仍复制了整个卡,并且B)您想要在图像中包括两个分区。

问题“ A”很容易解释:您仍在复制整个卡,因为这就是/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(每kB 2个扇区)/ 1024(kB每MB)/ 1024(MB每GB)= 12.69,我使用gparted扩展了分区到12 GB,所以这看起来是正确的(确实,我应该使用1000而不是1024作为带存储空间的除数,这可以达到13.31 GB,但是我怀疑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 MB!这是因为我实际用作count=200000参数,dd因为我真的不想打扰12 GB的副本(注意“总200000个扇区”)。底部的表不能反映这一点的原因是因为fdisk从SD卡的开头逐个复制映像中的分区数据来获取其信息,正如我在第二段中提到的那样,至关重要保持。如果我(正确地)复制了其余的内容,那么这些数字将是正确的,并且图像将是可行的。

试试看。:)


在OSX上,fdisk不能清楚地以字节为单位打印出扇区大小。而是提供“几何:966/255/63 [15523840个扇区]”,代表圆柱体/磁头/扇区。在这种情况下应使用bs和count的什么值?
亚瑟·赫伯特

@ArthurHebert:总字节数/总扇区数。例如在它上面的第一种情况下将是31520768分之16138633216= 512,在第二200000分之102400000= 512
金发

1
您可以使用fdisk -l <device>,并且应该在不进入交互模式的情况下打印表格。
berto

5

我猜问题在于曾经使用过的扇区中仍然有灰尘。删除文件后,只会从文件系统中删除元数据,而不会删除数据本身,因此会留下一些随机的零,而不是易于压缩仅零的块。

简单的解决方案,但需要重写卡上的所有可用空间。请记住,SD卡的生命周期受重写次数的限制,因此这不是首选方法。

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

解决方案涉及更多,因为您需要在另一台将不使用该SD卡的计算机上安装Zerofree

zerofree /dev/mmcblk0p2

有关更多信息,请访问http://intgat.tigress.co.uk/rmy/uml/index.html

您要记住的是,即使分区较小,执行/ dev / mmcblk0的dd也可以复制整个设备。如果在执行上述方法之一之前使用raspi-config扩展主分区,则可以。

PS:如果您不介意更改格式的图像文件,则可以使用partimage,对于已知的文件系统,partimage会忽略已释放的块,即使它们中仍有一些污垢。同样,未挂载文件系统时最好使用partimage以避免备份损坏。您可能可以以只读方式重新安装它,但是我将由您自行决定。


作为我尝试完成此任务的一部分,我使用gparted减少了sdcard分区以仅容纳我拥有的数据,然后尝试了dd ing,结果是相同的7.6GB文件,partimage无法保存2个分区(/开机+ /)成1张图片
mf_13年

也许我做得不够清楚-压缩它时应该有所作为,就像您之前使用gzip尝试过的那样。
RooTer

以这种方式填充卡会导致整个写入周期,并会缩短卡的使用寿命。试试dd bs=4M if=/dev/zero of=/root/junk
nc4pk

@ tapped-out thx,编辑;)
RooTer

4

简短答案-使用2GB SD卡。

长答案,dd不知道“好”数据在哪里结束,您必须以某种方式告诉它。

有两种方法,最简单的方法是使用2GB SD卡,它将自动停止复制超过2GB的数据,并根据需要生成500MB的压缩文件。

另一种方法(涉及的方法更复杂)是从分区表计算正确的数据大小,并将此正确的大小指定为dd命令参数。为此,您可以使用bs=XXX(块大小)和count=XXX(块计数)参数。例如,您可以指定bs=10M10MB的块大小(与您在命令中使用的4k块大小相比,这肯定会使复制更快)并count=200复制10MB * 200 = 2000MB(2GB)。您可能需要根据SD卡分区方案调整块大小和块数。


1
给予dd一个特定的大小将永远不要工作。假定文件系统中的所有实际数据都整齐地排列在设备的开头,因此,如果8GB分区上有2GB,则只需复制第一个2GB。这是假的。那2 GB的数据将散布在整个空间上,特别是在现代SD卡上,直到所有可用块都至少使用了一次,才重新使用块两次(这称为损耗平衡,这会延长卡的寿命)。
goldilocks

@goldilocks如果我要调整sdcard的大小以将所有分区缩小到最大可能的大小(仅数据),该怎么办?
mf_

@goldilocks,请更仔细地阅读问题和答案,我是在谈论8GB SD卡上的2GB分区,而不是关于8GB分区上的2GB数据,因为您的想象力以某种方式告诉了您。
lenik

1
lenik:是的,我有点惊讶,我以这种方式向您解释,所有的道歉-不幸的是,除非您编辑此帖子,否则我无法撤消我的投票:/尽管我仍然不认为这个答案特别有用(没有冒犯- -因为这不是简单地添加分区,有关如何执行此操作的说明仍然没有用),但是我会这样做。@mf_是的,这是可行的(您读了我的回答吗?会起作用...)
goldilocks

@goldilocks我已经编辑了答案。不知道为什么它没有用,特别是当您给出完全相同的答案时,只是带有更多详细信息。
lenik

1

dd - copy and convert不是完成所需工作的正确工具。这是一个低级别的逐扇区复制(和转换)工具,非常适合复制引导扇区,格式化设备以及各种低级任务。使用时dd,即使文件系统结构中未包含该映像,也要逐个扇区地将其复制到映像。

Raspberry Pi基金会提供的映像是经过特殊编译的映像,其中包含安装脚本,解压缩二进制文件和初始设置,之后无论如何您都必须从Internet获取更新-这都是有意的,但要使它像这样工作是一项艰巨的任务。

避免复制空扇区的一种流行解决方案是使用文件级复制系统-CloneZilla是独立的,可从CD启动,类似于ye olde Norton Ghost但clonezilla支持Linux(及更多)文件系统。因此,它将仅复制正在使用的文件,并仅从这些文件创建容器。大大减小尺寸!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.