想做个树莓派的img镜像,然而对SD卡进行全盘复制很浪费空间,且不能恢复到比现有SD卡容量小的卡上,因此探索制作小img的方法,网上看了大神制作的脚本,比如https://github.com/conanwhf/RaspberryPi-script/blob/master/rpi-backup.sh和https://github.com/elespec/rpi-backup/blob/master/rpi-backup.sh,然而做好之后在我的树莓派上无法启动。最终参考了这篇文章的方法:手动一步一步来制作备份Raspberry Pi树莓派SD卡的img映像文件(不用dd命令),感谢原作者分享。结合这些修改成了一个脚本。我的树莓派是Raspbain Stretch系统
使用时将树莓派的SD卡插到PC上,用PC制作img镜像,最后img文件会放在~/bakcup_img/文件夹下,测试所用PC的操作系统是Ubuntu16.04。

目录

  • 查看SD卡挂载信息
  • 脚本自动备份
  • 手动备份
    • 准备工作
    • 创建空白img文件
    • 格式化img文件分区并挂载
    • 备份/boot
    • 备份"/"
    • 相应修改PARTUUID设定
      • 修改 cmdline.txt 文件
      • 修改fstab文件
    • 收尾

查看SD卡挂载信息

PC端SD卡已经自动挂载好了,使用df -h查看SD卡对应的设备名和使用的空间大小

df -h


设备名/dev/mmcblk0p1/dev/mmcblk0p2,根据空间大小判断/dev/mmcblk0p1/boot/dev/mmcblk0p2/(根)
根据原文步骤,简化了一些写成脚本,可以先按照脚本自动备份这一节提供的脚本运行,也可以按照手动备份的方法一步步执行。

脚本自动备份

将脚本复制到一个文本文件中,假设名字为rpi-backup.sh,需要赋可执行权限,脚本执行有两个参数,第一个参数是树莓派SD卡/boot分区的设备名,第二个参数是/分区的设备名。最终img文件会生成在~/backupimg/文件夹下。

sudo chmod +x rpi-backup.sh
./rpi-backup.sh /dev/mmcblk0p1 /dev/mmcblk0p2

脚本内容如下:

#!/bin/shif [  $# != 2 ]; thenecho "argument error: Usage: $0 boot_device_name root_device_name"echo "example: $0 /dev/mmcblk0p1 /dev/mmcblk0p2"exit 0
fi
dev_boot=$1
dev_root=$2
mounted_boot=`df -h | grep $dev_boot | awk '{print $6}'`
mounted_root=`df -h | grep $dev_root | awk '{print $6}'`
img=rpi-`date +%Y%m%d-%H%M`.img#install tools
sudo apt-get install dosfstools dump parted kpartxecho =====================   part 1, prepare workspace    ===============================
mkdir ~/backupimg
cd ~/backupimgecho ===================== part 2, create a new blank img ===============================
# New img file
#sudo rm $imgbootsz=`df -P | grep $dev_boot | awk '{print $2}'`
rootsz=`df -P | grep $dev_root | awk '{print $3}'`
totalsz=`echo $bootsz $rootsz | awk '{print int(($1+$2)*1.3/1024)}'`
sudo dd if=/dev/zero of=$img bs=1M count=$totalsz
#sync
echo "...created a blank img, size ${totalsz}M "# format virtual disk
bootstart=`sudo fdisk -l | grep $dev_boot | awk '{print $2}'`
bootend=`sudo fdisk -l | grep $dev_boot | awk '{print $3}'`
rootstart=`sudo fdisk -l | grep $dev_root | awk '{print $2}'`
echo "boot: $bootstart >>> $bootend, root: $rootstart >>> end"
#有些系统 sudo fdisk -l 时boot分区的boot标记会标记为*,此时bootstart和bootend最后应改为 $3 和 $4
#rootend=`sudo fdisk -l /dev/mmcblk0 | grep mmcblk0p2 | awk '{print $3}'`sudo parted $img --script -- mklabel msdos
sudo parted $img --script -- mkpart primary fat32 ${bootstart}s ${bootend}s
sudo parted $img --script -- mkpart primary ext4 ${rootstart}s -1echo =====================  part 3, mount img to system  ===============================
loopdevice=`sudo losetup -f --show $img`
device=/dev/mapper/`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/\1/g' | head -1`
sleep 5
sudo mkfs.vfat ${device}p1 -n boot
sudo mkfs.ext4 ${device}p2 -L rootfs
#在backupimg文件夹下新建两个文件夹,将两个分区挂载在下面
mkdir tgt_boot tgt_Root
#这里没有使用id命令来查看uid和gid,而是假设uid和gid都和当前用户名相同
uid=`whoami`
gid=$uid
sudo mount -t vfat -o uid=${uid},gid=${gid},umask=0000 ${device}p1 ./tgt_boot/
sudo mount -t ext4 ${device}p2 ./tgt_Root/echo ===================== part 4, backup /boot =========================
sudo cp -rfp ${mounted_boot}/* ./tgt_boot/
sync
echo "...Boot partition done"echo ===================== part 5, backup / =========================
sudo chmod 777 ./tgt_Root
sudo chown ${uid}.${gid} tgt_Root
sudo rm -rf ./tgt_Root/*
cd tgt_Root/
# start backup
sudo dump -0uaf - ${mounted_root}/ | sudo restore -rf -
sync
echo "...Root partition done"
cd ..echo ===================== part 6, replace PARTUUID =========================# replace PARTUUID
opartuuidb=`sudo blkid -o export $dev_boot | grep PARTUUID`
opartuuidr=`sudo blkid -o export $dev_root | grep PARTUUID`
npartuuidb=`sudo blkid -o export ${device}p1 | grep PARTUUID`
npartuuidr=`sudo blkid -o export ${device}p2 | grep PARTUUID`
sudo sed -i "s/$opartuuidr/$npartuuidr/g" ./tgt_boot/cmdline.txt
sudo sed -i "s/$opartuuidb/$npartuuidb/g" ./tgt_Root/etc/fstab
sudo sed -i "s/$opartuuidr/$npartuuidr/g" ./tgt_Root/etc/fstab
echo "...replace PARTUUID done"echo "remove auto generated files"
#下面内容是删除树莓派中系统自动产生的文件、临时文件等
cd ~/backupimg/tgt_Root
sudo rm -rf ./.gvfs ./dev/* ./media/* ./mnt/* ./proc/* ./run/* ./sys/* ./tmp/* ./lost+found/ ./restoresymtable
cd ..echo ===================== part 7, unmount =========================
sudo umount tgt_boot tgt_Root
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice
rmdir tgt_boot tgt_Rootecho "==== All done. img file is under ~/backupimg/ "

手动备份

准备工作

安装工具软件

sudo apt-get install dosfstools dump parted kpartx

建立工作目录

mkdir ~/backupimg
cd ~/backupimg

创建空白img文件

源SD卡已使用空间大概3.5G,就创建了4600M大小的img文件

sudo dd if=/dev/zero of=raspberrypi.img bs=1M count=4600

原博客中有提示:

特别注意这里 bs=1M,千万不要写成1MB
1M是1024*1024 Bytes, 而1MB是1000*1000 Bytes,会造成img文件的大小不是512 bytes的整数倍,后面会报错。


查看分区表

sudo fdisk -l


给img文件分区
按照原来的起始位置设置分区

注:分区的起始扇区数都是 8192 的倍数,保证4K对齐

sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 96042s
#第二个分区的终止点为img文件的末尾
sudo parted raspberrypi.img --script -- mkpart primary ext4 98304s -1

检查分区是否成功

sudo parted raspberrypi.img


在(parted)后面输入print free,最后输入quit退出。

格式化img文件分区并挂载

查看img文件对应的Loop device的设置

sudo losetup -f --show raspberrypi.img

下面的命令中相应输入/dev/loop0,如果不是 loop0 请做相应调整(以及以后的各个步骤里的loop0都要改变)

sudo kpartx -va /dev/loop0

终端输入ls /dev/mapper/loop0p*应该是有/dev/mapper/loop0p1 /dev/mapper/loop0p2两个设备。
其中loop0p1是/boot,loop0p2是根。
格式化、挂载:

sudo mkfs.vfat -n boot /dev/mapper/loop0p1
sudo mkfs.ext4 -L rootfs /dev/mapper/loop0p2
#在backupimg文件夹下新建两个文件夹,将两个分区挂载在下面
mkdir tgt_boot tgt_Root
sudo mount -t vfat -o uid=zk,gid=zk,umask=0000 /dev/mapper/loop0p1 ./tgt_boot/
sudo mount -t ext4 /dev/mapper/loop0p2 ./tgt_Root/

上面的uid和gid根据自己系统的用户名有所变化。

备份/boot

直接拷贝
下面命令中的/media/zk/boot/*要根据自己系统中树莓派SD卡的挂载位置进行修改。

sudo cp -rfp /media/zk/boot/* ./tgt_boot/

备份"/"

原文中提供了两种方法,本人尝试时只用了第一种:dump/restore方法
对目标挂载点设置合适的权限,并清空

sudo chmod 777 ./tgt_Root
#下面的zk.zk与上文提到的uid,gid设置一致,需要根据系统的用户名去修改
sudo chown zk.zk tgt_Root
sudo rm -rf ./tgt_Root/*
cd tgt_Root/

开始备份
#下面命令中的/media/zk/rootfs/要根据自己系统中树莓派SD卡的挂载位置进行修改

sudo dump -0uaf - /media/zk/rootfs/ | sudo restore -rf -
#返回上层目录
cd ..


耗时几分钟,运行完后可以查看下tgt_Root下是否已把文件备份过来

相应修改PARTUUID设定

这时候整个备份就已经完成了。不过此时的img文件即使写入到空白SD卡里面也是无法启动的,因为Raspbian启动要对应分区的PARTUUID,所以我们还要修改目标img文件里的如下两个文件:

./tgt_boot/cmdline.txt
./tgt_Root/etc/fstab

首先查看img文件对应的loop device的两个分区的PARTUUID

sudo blkid

在输出的信息里查看到:
/dev/mapper/loop0p1PARTUUID是“961e1351-01”,
/dev/mapper/loop0p2PARTUUID是“961e1351-02”。

修改 cmdline.txt 文件

将其中root=PARTUUID=af2f8761-02部分改为/dev/mapper/loop0p2(即根分区)的PARTUUID,修改后如下:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=961e1351-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

修改fstab文件

proc            /proc           proc    defaults          0       0
PARTUUID=961e1351-01  /boot           vfat    defaults          0       2
PARTUUID=961e1351-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

收尾

卸载各个挂载的分区,删除loop device,删除挂载点目录

sudo umount tgt_boot tgt_Root
sudo kpartx -d /dev/loop0
sudo losetup -d /dev/loop0
rmdir tgt_boot tgt_Root

完成之后可以用dd或者Etcher烧写img文件到其他SD卡中,注意烧写到新卡中在树莓派中运行后,要用raspi-config先把分区空间expand一下,否则可用空间会很小。

制作树莓派img镜像文件相关推荐

  1. 【Docker镜像文件加载原理生产中重新制作并提交镜像文件案例演示】

    一.知识回顾 之前的内容都帮你整理好了,在这里哟! [0.Docker相关目录文章整理,可自行查看,包含多节内容] [1.Docker详细安装部署&阿里镜像地址配置] [2.Docker架构& ...

  2. 在Mac上制作树莓派SD镜像

    先记录下,等有空翻译下,在Mac上制作树莓派的镜像还是比较麻烦的,好处是不需要第三方软件,用命令行就可以了.在windows上就比较简单. On Mac OS you have the choice ...

  3. 【树莓派】制作树莓派最小镜像:img裁剪瘦身

    摘录部分要点内容如下(如果作者不允许转载,请联系即删除): 一.查看当前系统所占容量  用Win32DiskImager来制作镜像时是将sd卡正卡全部做成镜像,是因为无法读取到linux分区的原因,所 ...

  4. 树莓派入门教程 - 0 - 准备篇 - 0.0 SD卡制作树莓派系统镜像启动盘 开机

    电脑需要提前安装的工具: sd卡格式化工具 SDFormatter,官网下载链接:https://www.sdcard.org/downloads/formatter/ 镜像烧录工具 Win32 Di ...

  5. 制作linux安装镜像文件,制作CentOS 6.5一键自安装ISO镜像光盘 | 聂扬帆博客

    因为工作中需要经常安装系统并且会有一些定制的系统包和软件.定制ISO可以大大减轻运维的负担.本文以Centos 6.5制作为例 一.系统安装包说明 目录树结构 |-- .discinfo |-- .t ...

  6. Linux 下制作光盘 ISO 镜像文件

    前提 由于当前重装系统, 缺少了 intel 驱动, 导致网络无法使用 解决方法 制作 ISO 镜像文件 利用 IDRAC 卡中, 直接导入 ISO 文件方法, 导入文件 实现 1. 把需要的 RPM ...

  7. android img 制作工具,Android 镜像文件制作 【ramdisk.img system.img userdata.img】

    Android项目生成的镜像文件包括ramdisk.img, system.img, userdata.img ramdisk.img 是out/target/product/项目名/root 目录经 ...

  8. Alcohol 120%刻录教程:制作镜像文件

    Alcohol 120%下载 把要制作镜像文件的源光盘放进光驱(读取光盘驱动器并不定非要刻录机不可),点击桌面上的快捷方式图标运行Alcohol 120%,在程序主界面上 点击左边[主要功能]菜单栏上 ...

  9. linux下制作windows镜像文件,Linux之自定义ISO镜像文件制作

    这一节主要介绍iso镜像制作过程,主要包含两部分mkisofs:创建镜像文件 光盘烧录工具 如果终端没有mkisofs指令,需要下载一下,例如ubuntu14.04 apt-get install g ...

最新文章

  1. c#中分割字符串的几种方法
  2. port常用和不常用端口一览表
  3. 排查链接是否失效_如何进行移动站点流量排查?
  4. Intel视频处理与分析技术栈和架构纵览
  5. java.util.Properties
  6. 手机连接电脑wifi
  7. python matplotlib使用ax绘图
  8. 深度学习AI美颜系列---AI美颜磨皮算法一
  9. mysql i优化_mysql优化 - ifeixiang的个人页面 - OSCHINA - 中文开源技术交流社区
  10. JDK1.8下载与安装及环境变量配置
  11. Unity射线检测整理
  12. spring 自动装配 bean 有哪些方式?
  13. e4a和php教程,2019开源影视APP优化运营版+对接苹果cms10+全套类库E4A资源+开发文档+搭建教程源码...
  14. Golang学习+深入(十三)-goroutine/channal
  15. Java干货(一)----Java重写时应当遵守的10条规则
  16. 虚拟机VMware安Mac OS时没有Apple mac选项
  17. 项目前期准备的重要性
  18. 网络安全——无线局域网安全技术——802.11i
  19. REID重识别的一些思考-REID场景介绍-初探(一)
  20. 公司电脑usb被禁用,如何重新启用usb功能?

热门文章

  1. 一个可以地址和各种格式的经纬度查询互换的网址,支持百度、高德、Google等地图对比查询。
  2. 开源飞控APM与PIXHAWK
  3. 2019.5.10 硬盘的区分IDE、SATA、SCSI和光纤通道
  4. 海康威视道闸进出口LED屏DS-TVL224系列开发C#源码
  5. 半导体元件、芯片、处理器、CPU、MCU的区别
  6. Java实现身份证识别注册
  7. Word里mathtype公式显示不全
  8. centos7.2 bt面板安装redis一些注意事项
  9. 笔记 GWAS 操作流程2-6:去掉亲缘关系近的个体
  10. 饲料混合加工问题——原料间亲缘值计算