首页 树莓派正文

制作树莓派最小镜像 SD卡系统备份

云水 树莓派 2019-10-27 21:06:02 1586 0 树莓派

最近刚做了一套OpenCV摄像头监控的程序,想将这套程序做一个镜像备份起来,但发现用Win32DiskImager或dd命令来制作镜像,都是将sd卡整盘进行备份,造成了巨大的硬盘浪费,同时,会局限sd卡本身,也就是说32g卡制作的镜像无法恢复到16g或8g的卡上,即便软件没有占用那么大空间,所以希望将镜像瘦身,做一套最小占用空间的镜像,且不损害镜像本身。

前不久在csdn上看到 liuwei000000的博文与我所希望的结果差不多,所以试着进行一次img瘦身。 
不过该博文也有缺点“该方法制作的镜像不能用raspi-config扩展分区”所以即便我们能够将img瘦身也不能轻松的利用raspi-config扩展树莓派了,所以我提炼了奋斗博客博文亲身制作了一把img,并把遇到的问题记录了下来

我使用的的是raspberry pi 2+32G高速tf卡,因为全程只在树莓派中操作所以不需要额外的Linux系统。

若树莓派所占空间小于sd卡空间的50%即可以使用第一种方法,在树莓派内部直接生成镜像。 
若树莓派所占空间大于sd卡空间的50%,可以使用第二种方法,先生成sd卡镜像,然后再其他linux系统中进行裁剪。

在文后,我会提供一键脚本。


树莓派内部生成镜像

一、查看当前系统所占容量 
用Win32DiskImager来制作镜像时是将sd卡正卡全部做成镜像,是因为无法读取到linux分区的原因,所以我们在制作镜像前,先要确定我们当前系统所占用了多少系统空间,即备份镜像的大小。

#查看当前系统所占用的空间
df -h

这里写图片描述 
可以看到,树莓派是有两个分区,所以boot 【size】+linux【Used】+分区损耗【因为格式转换,所以会损耗5%~10%】=镜像实际大小,所以若used使用百分比超过50%那么就无法在sd中创建此镜像。

二、安装需要的软件 
dosfstools:fat32分区格式化工具 
dump:dump & restore 备份工具 
parted & kpartx:虚拟磁盘工具

sudo apt-get install dosfstools dump parted kpartx

三、生成空白img 
根据一里面系统所占用的空间,生成空白的img。

#df为磁盘占用空间
sudo dd if=/dev/zero of=raspberrypi.img bs=1K count=$df

这也是错误比较多的地方,有人不理解原文中count=2500参数的意义,此参数是用dd命令创建一个大约2.5G的空白镜像,若不使用第一步来算出实际镜像大小的话,制作出来的镜像就会出错

此处注意 
dd命令中【1k=1024b;1KB=1000b;1M=1024kb;1MB=1000kb】

四、分割虚拟磁盘 
我们已将空白的img创建完毕,现在需要通过parted将磁盘分为boot与root区 
通过sudo fdisk -l /dev/mmcblk0得知 
这里写图片描述 
第一个分区为boot分区,采用FAT32格式,由sector 8192开始到sector 12879 
第二个分割区采用EXT4,由sector 122880开始到空白img结尾。

sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 122879s
sudo parted raspberrypi.img --script -- mkpart primary ext4 122880s -1

五、挂载虚拟磁盘并格式化

loopdevice:执行 losetup 连接 img 文件的 loop device 
device:执行完 kpartx 后,虚拟磁盘代号。 
partBoot:由 device 加上 p1 组合而成的 FAT32 虚拟磁盘分区。 
partRoot:由 device 加上 p2 组合而成的 EXT4 虚拟磁盘分区。

首先建立虚拟磁盘并分区

loopdevice=`sudo losetup -f --show raspberrypi.img`
device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1`
device="/dev/mapper/${device}"
partBoot="${device}p1"
partRoot="${device}p2"

然后格式化虚拟磁盘分区

#boot分区用fat32进行格式化
sudo mkfs.vfat $partBoot
sudo mkfs.ext4 $partRoot

六、开始备份 
boot分区为fat32格式,可以直接利用cp命令直接拷贝

sudo mount -t vfat $partBoot /media
sudo cp -rfp /boot/* /media/
sudo umount /media

linux分区为ext4格式,需要利用dump & restore备份

#跳过raspberrypi.img不备份
sudo chattr +d raspberrypi.img
sudo mount -t ext4 $partRoot /media/
cd /media
sudo dump -h 0 -0uaf - / | sudo restore -rf -
cd
sudo umount /media

这里原文中也有一点bug,用dump进行磁盘备份时,会将之前创建的空白img一并备份进去,通过chattr跳过raspberrypi.img

七、备份完毕,卸载虚拟磁盘 
此时,已将所有数据备份至空白img,此时就可以卸载虚拟磁盘,将img拷贝出保存了。 
然后利用Win32DiskImager或者df命令即可将该raspberrypi.img恢复至sd卡上。

sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice

这里是整理后的脚本,编辑sudo vi backup.sh,复制以下内容,sudo chmod 777 backup.sh,然后sudo ./backup.sh就可以在当前脚本目录中生成树莓派的SD卡镜像了。

脚本经过以下固件版本测试:

2015-02-16-raspbian-wheezy

#!/bin/sh
sudo apt-get install -y dosfstools dump parted kpartx
df=`df -P | grep /dev/root | awk '{print $3}'`
df=`echo $df |awk '{print int($1*1.1+57344)}'`
sudo dd if=/dev/zero of=raspberrypi.img bs=1K count=$df
sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 122879s
sudo parted raspberrypi.img --script -- mkpart primary ext4 122880s -1
loopdevice=`sudo losetup -f --show raspberrypi.img`
device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1`
device="/dev/mapper/${device}"
partBoot="${device}p1"
partRoot="${device}p2"
sudo mkfs.vfat $partBoot
sudo mkfs.ext4 $partRoot
sudo mount -t vfat $partBoot /media
sudo cp -rfp /boot/* /media/
sudo umount /media
sudo chattr +d raspberrypi.img
sudo mount -t ext4 $partRoot /media/
cd /media
sudo dump -h 0 -0uaf - / | sudo restore -rf -
cd
sudo umount /media
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice1

脚本经过以下固件版本测试:

2016-05-27-raspbian-jessie

#!/bin/sh
sudo apt-get install -y dosfstools parted kpartx rsync
df=`df -P | grep /dev/root | awk '{print $3}'`
dr=`df -P | grep /dev/mmcblk0p1 | awk '{print $2}'`
df=`echo $df $dr |awk '{print int(($1+$2)*1.2)}'`
sudo dd if=/dev/zero of=raspberrypi.img bs=1K count=$df
sudo parted raspberrypi.img --script -- mklabel msdos
start=`sudo fdisk -l /dev/mmcblk0| awk 'NR==10 {print $2}'`
start=`echo $start's'`
end=`sudo fdisk -l /dev/mmcblk0| awk 'NR==10 {print $3}'`
end2=$[end+1]
end=`echo $end's'`
end2=`echo $end2's'`

sudo parted raspberrypi.img --script -- mkpart primary fat32 $start $end
sudo parted raspberrypi.img --script -- mkpart primary ext4 $end2 -1

loopdevice=`sudo losetup -f --show raspberrypi.img`
device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1`
device="/dev/mapper/${device}"
partBoot="${device}p1"
partRoot="${device}p2"
sudo mkfs.vfat $partBoot
sudo mkfs.ext4 $partRoot
sudo mount -t vfat $partBoot /media
sudo cp -rfp /boot/* /media/
sudo umount /media
sudo mount -t ext4 $partRoot /media/
cd /media
sudo rsync -aP --exclude="raspberrypi.img" --exclude=/media/* --exclude=/sys/* --exclude=/proc/*  --exclude=/tmp/* / ./
cd
sudo umount /media
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice
如果以上比较简单的脚本还是不行的话,可以用以下终极解决方案。
http://www.360doc.com/content/17/0805/03/40492717_676751545.shtml


版权声明

1.本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行测试。
2.本站资源仅供学习和交流使用,版权归资源原作者所有,请在下载后24小时之内自觉删除。
3.若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,与本站无关。
4.若内容涉及侵权或违法信息,请联系本站管理员进行下架处理,邮箱ganice520@163.com(本站不支持其他投诉反馈渠道,谢谢合作)

本文链接:http://www.apod.cc/index.php/post/86.html

发表评论

评论列表(0人评论 , 1586人围观)
☹还没有评论,来说两句吧...