在 Linux 中,我们可以做
dd if=/dev/sdb of=bckup.img
但是如果磁盘是 32GB,只使用了 4GB,那么 32GB 的图像文件就是浪费空间。是否有任何方法或工具可以仅使用有效数据创建图像?
处理这个问题的非常好的和简单的方法是简单地通过 gzip 进行管道传输,如下所示:
# dd if=/dev/sdb | gzip > backup.img.gz
这样,您的图像将被压缩,并且很可能未使用的空间将被压缩到几乎没有。
您将使用它来恢复此类图像:
# cat backup.img.gz | gunzip | dd of=/dev/sdb
注意:如果您最近删除了很多文件,则图像大小可能仍然很大(删除文件不一定会使底层扇区归零)。您可以通过创建并立即删除包含零的大文件来擦除可用空间:
# cd /media/flashdrive
# dd if=/dev/zero of=bigfile bs=1M # let it run and quit by disk full error
# rm bigfile
最好的办法是
从保留元数据的所有分区中复制所有文件
mkdir -p myimage/partition1
mkdir myimage/partition2
sudo cp -rf --preserve=all /media/mount_point_partition1/* myimage/partition1/
sudo cp -rf --preserve=all /media/mount_point_partition2/* myimage/partition2/
提取 MBR
sudo dd if=/dev/sdX of=myimage/mbr.img bs=446 count=1
更换/dev/sdX
相应的设备。
将目标磁盘分区为大小大于复制数据的分区,并且应该使用相同的格式和相同的标志gparted
。谷歌如何对磁盘进行分区。
挂载新格式化和分区的磁盘。在大多数计算机上,您只需连接磁盘,即可在/media
文件夹中找到已安装的分区。
使用以下命令将先前复制的数据复制到目标分区
sudo cp -rf --preserve=all myimage/partition1/* /media/mount_point_partition1/
sudo cp -rf --preserve=all myimage/partition2/* /media/mount_point_partition2/
复制回 MBR
sudo dd if=myimage/mbr.img of=/dev/sdX bs=446 count=1
现在享受你的新磁盘!
使用 的bs和count参数dd
,您可以限制图像的大小,如答案 1665017的步骤 2 所示。
您可能已经知道要创建什么尺寸的图像。如果没有,您可以从以下方面获得一个好主意df
:
df -H --total /
替换/
为与磁盘分区相关的所有挂载点的空格分隔列表。
更准确的方法可能是使用fdisk
或您喜欢的分区编辑器并忙于使用计算器。
$ fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 7.4 GiB, 7948206080 bytes, 15523840 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
Disklabel type: dos
Disk identifier: 0x00057540
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 2048 186367 184320 90M c W95 FAT32 (LBA)
/dev/mmcblk0p2 186368 3667967 3481600 1.7G 5 Extended
/dev/mmcblk0p5 188416 3667967 3479552 1.7G 83 Linux
以字节为单位的总已用空间 = 最后一个分区的结束扇区 X 扇区大小(此处为 3667967 x 512)。
以 GB 为单位的总已用空间 = 以字节为单位的总已用空间 / 1024 3(此处为 1.749023 GB)。
例如,如果您决定您的映像应该正好是 2 GB,则以下命令将执行此操作:
dd if=/dev/mmcblk0 of=/path/to/pi_updated.img bs=1M count=2048
生成的图像还将包括超出最后一个分区最大范围的随机噪声。
sudo
如果您的帐户还没有足够的权限,请不要忘记上述命令。
出于我的目的,我不需要完美修剪到最后一点数据的图像,因此当实际大小为 1.75 GB 时,2 GB 的图像对我来说就足够了。这会减少映像中其他 6 GB(或 30 GB 或任何设备有空闲的空间)的未使用空间。
我在很多地方都看到了不dd
应该在已挂载的分区上执行的建议,我遵循了这些建议,因为它看起来直观正确;它看起来更像是试图勾勒自己在镜子中制作草图,而您正在制作的草图在草图中也可见。这有点粗略。
在尝试了多种不同的方法后,我发现了以下文章:
https://medium.com/platformer-blog/creating-a-custom-raspbian-os-image-for-production-3fcb43ff3630
它的创建是为了缩小和调整(在第一次启动时)树莓派图像的大小,但可以很容易地针对任何其他 Linux 发行版进行调整。我成功地让它与 Debian 9 一起在基于 arm 的定制芯片上工作。
pishrink脚本rc.local
创建的首先raspi-config
用于调整 rootfs 的大小,然后回退到使用的方法parted
(我必须提前在我的机器上安装)。我注释掉了.raspi-config
我的 sd 卡映像从 15 GB 缩小到 1.1 GB。我用etcher 刷新了缩小的 sd-card 图像。完整的 15 GB 映像耗时不到 5 分钟,而不是半小时以上
如果您有一张 16 GB、32 GB 等的大型 SD 卡,但您想通过备份节省空间,您可以使用:
sudo apt-get install gnome-disk-utility
打开磁盘实用程序来检查你的 U 盘是否真的有:
gnome-disks
在我的例子中,一张带有 Raspbian 映像的 32GB SD 卡被识别为:/dev/sde
所以我运行/dev/sde
:
sudo dd bs=4M status=progress if=/dev/sde | gzip > \
/you-selected-full-path-here/raspberry-images/`date +%Y%m%d`_rpi_image_backup.gz
status=progress gives you progress bar indication
| gzip > compresses the 32 GB total size and not writing the empty space from the 32 GB
`date +%Y%m%d` writes today date in the filename
输出:20190529_rpi_image_backup.gz
而且大小只有3.5GB。如果您想将此图像写入新的 SD 卡,请使用:
您也可以将这个由 32 GB 制作的图像写入 16 GB 或 8 GB 的磁盘,不再抱怨图像太大了。
我制作自定义 raspios 图像的解决方案:
DIR="./img"
DEVICE=/dev/sdb
# declare custom copy functions
copy() {
echo "[$1] copy $2 to $3..."
if [ "$1" == 'ext' ]; then
sudo rsync -aHAXX \
--no-inc-recursive \
--numeric-ids \
--filter='-x security.selinux' \
--delete \
--exclude={"/lost+found"} \
--info=progress2 \
$2 \
$3
else
sudo rsync -rtD \
--modify-window=1 \
--no-inc-recursive \
--delete \
--exclude={"/lost+found"} \
--info=progress2 \
$2 \
$3
fi
}
# create working directories
mkdir -p $DIR/{mount,image}/{boot,rootfs}
# mount initial device partitions
sudo mount ${DEVICE}1 $DIR/mount/boot
sudo mount ${DEVICE}2 $DIR/mount/rootfs
# preserve partitions UUIDs
PTUUID=0x`sudo blkid -p $DEVICE | sed -e 's/.*PTUUID="\([0-9a-f]*\)".*/\1/'`
BOOTUUID=`sudo blkid -p ${DEVICE}1 | sed -e 's/.* UUID="\([0-9a-zA-Z\-]*\)".*/\1/' | tr -d '-'`
ROOTUUID=`sudo blkid -p ${DEVICE}2 | sed -e 's/.* UUID="\([0-9a-zA-Z\-]*\)".*/\1/'`
# copy contents from physical device to local folder
copy fat $DIR/mount/boot/ $DIR/image/boot/
copy ext $DIR/mount/rootfs/ $DIR/image/rootfs/
umount ${DEVICE}1
umount ${DEVICE}2
# show contents size
BOOTSIZE=`sudo du -hs $DIR/image/boot`
ROOTSIZE=`sudo du -hs $DIR/image/rootfs`
echo "boot is $BOOTSIZE"
echo "root is $ROOTSIZE"
# allocate the final .img file
# change size as needed
SIZE="5"
echo "allocating ${SIZE}G image..."
rm $DIR/$IMAGE
fallocate -l ${SIZE}G $DIR/$IMAGE
# create partitions
echo "formatting image..."
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk $DIR/$IMAGE > /dev/null
o # create MBR partition scheme
n # new partition
p # primary
1 # partition #1
8192 # start block
532479 # end block
t # define type
0c # W95 FAT32 (LBA)
n # new partition
p # primary
2 # partition #2
532480 # start block
# last end block
t # define type
2 # for partition #2
83 # linux
x # advanced menu
i # change disk identifier
$PTUUID # identifier from original fstab
r # return to normal menu
w # write changes
EOF
# locally mount the .img
echo "mounting image..."
LOOP=`sudo losetup -fP --show $DIR/$IMAGE`
echo "mounted image under $LOOP"
ls -la $LOOP*
echo "creating partition boot with FAT32"
sudo mkfs.fat \
-F 32 \
-S 512 \
-i $BOOTUUID \
-n boot \
${LOOP}p1
echo "creating partition rootfs with ext4"
sudo mkfs.ext4 \
-b 4096 \
-U $ROOTUUID \
-L rootfs \
${LOOP}p2
echo "mounting image loops"
sudo mount ${LOOP}p1 $DIR/mount/boot
sudo mount ${LOOP}p2 $DIR/mount/rootfs
echo "copying contents to image"
copy fat $DIR/image/boot/ $DIR/mount/boot/
copy ext $DIR/image/rootfs/ $DIR/mount/rootfs/
echo "unmounting image"
unmount "$LOOP+" > /dev/null
echo "removing loop"
sudo losetup -d ${LOOP}
将可启动的 Ubuntu 持久 live USB 与 usbdata 分区中的图像文件插入单板计算机,例如 UP² Board。引导至 USB(默认持久实时选项)。启动终端并输入以下命令(单行):
sudo dd if=/media/ubuntu/usbdata/ubuntu.img of=/dev/mmcblk0 bs=1M status=progress
等待 15-20 分钟。完成后,关闭并断开 USB。引导至内部 eMMC 驱动器
从内部 eMMC 创建未压缩的稀疏图像文件并保存到闪存驱动器
sudo dd if=/dev/mmcblk0 bs=1M status=progress | cp --sparse=always /dev/stdin /media/ubuntu/usbdata/ubuntu.img
将未压缩的图像文件提取到内部 eMMC
sudo dd if=/media/ubuntu/usbdata/ubuntu.img of=/dev/mmcblk0 bs=1M status=progress
从内部 eMMC 创建压缩图像文件并保存到桌面
sudo dd if=/dev/mmcblk0 bs=1M status=progress | gzip > /home/user/Desktop/ubuntu.img.gz
将压缩图像文件提取到内部 eMMC
sudo gzip -cd /home/user/Desktop/ubuntu.img.gz | dd of=/dev/mmcblk0 bs=1M status=progress
资料来源: http ://dustymabe.com/2012/11/15/create-a-disk-image-without-enough-free-space/ https://forum.up-community.org/discussion/1197/solved-克隆上板的图像
sudo mkdir /media/root
sudo mount -t ext4 -o loop,offset=537919488 /media/user/usbdata/ubuntu.img /media/root
要确定映像或驱动器的偏移量,请运行:
fdisk -l /media/user/usbdata/ubuntu.img
然后,将 512 字节的块大小乘以 Linux 分区的起始块 1050624。512*1050624 = 537,919,488
同时挂载其他系统文件夹:
for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /media/root$i; done
然后 cd 进入 img 和 chroot 的根文件夹:
cd /media/root
sudo chroot .
然后您可以更新文件、密码等。要卸载,请运行:
for i in /dev /dev/pts /proc /sys /run; do sudo umount /media/root$i; done
sudo umount /media/root
创建 Ubuntu 持久实时 USB 映像 按照以下步骤使用 Ubuntu 的持久实时安装来刷新 USB 驱动器:https ://www.howtogeek.com/howto/14912/create-a-persistent-bootable-ubuntu-usb-flash-驾驶/