树莓派系统镜像基本操作

背景

以下操作均在Liunx环境下进行使用命令进行,Windows可以采用一些可视化工具操作。

其中备份文件压缩部分,在Mac环境下无法执行。

树莓派的系统放在TF存储卡上,在进行系统导入,备份时,需通过读卡器连接电脑。

系统镜像准备

树莓派的操作系统镜像文件有两种方式获取:

  • 通过访问树莓派官方网站下载最新版系统镜像获取。
  • 通过直接把已装好系统的树莓派存储卡直接导出为img镜像文件获取。也就是我们后续说到的导出系统备份文件。

系统镜像导入TF卡

  • 将树莓派的TF卡通过读卡器连接电脑

  • 查看TF卡所在的盘符:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    zhengk@ubuntu:/tmp$ sudo fdisk -l
    Disk /dev/sdc:14.5 GiB,15523119104 字节,30318592 个扇区
    单元:扇区 / 1 * 512 = 512 字节
    扇区大小(逻辑/物理):512 字节 / 512 字节
    I/O 大小(最小/最佳):512 字节 / 512 字节
    磁盘标签类型:dos
    磁盘标识符:0xd602174c

    设备 启动 起点 末尾 扇区 大小 Id 类型
    /dev/sdc1 8192 137215 129024 63M c W95 FAT32 (LBA)
    /dev/sdc2 137216 11130552 10993337 5.2G 83 Linux

    可见,TF卡被挂载在/dev/sdc上。

  • 弹出TF卡所在的盘符:

    这里unmount操作,是为了防止挂载之后存在其他进程访问而导致后续操作失败,所以必须先进行unmount操作。

    1
    2
    zhengk@ubuntu:/tmp$ umount /dev/sdc1
    zhengk@ubuntu:/tmp$ umount /dev/sdc2
  • 重建分区:

    步骤入下:

    • p选项查看分区
    • d选项删除分区
    • n选项新建分区
    • t选项修改分区类型
    • w选项写入使生效
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    zhengk@ubuntu:/tmp$ sudo fdisk /dev/sdc

    欢迎使用 fdisk (util-linux 2.31.1)。
    更改将停留在内存中,直到您决定将更改写入磁盘。
    使用写入命令前请三思。


    命令(输入 m 获取帮助): p
    Disk /dev/sdc:14.5 GiB,15523119104 字节,30318592 个扇区
    单元:扇区 / 1 * 512 = 512 字节
    扇区大小(逻辑/物理):512 字节 / 512 字节
    I/O 大小(最小/最佳):512 字节 / 512 字节
    磁盘标签类型:dos
    磁盘标识符:0xcd48578f

    设备 启动 起点 末尾 扇区 大小 Id 类型
    /dev/sdc1 8192 96042 87851 42.9M c W95 FAT32 (LBA)
    /dev/sdc2 98304 6799359 6701056 3.2G 83 Linux

    命令(输入 m 获取帮助): d
    分区号 (1,2, 默认 2):

    分区 2 已删除。

    命令(输入 m 获取帮助): d
    已选择分区 1
    分区 1 已删除。

    命令(输入 m 获取帮助): n
    分区类型
    p 主分区 (0个主分区,0个扩展分区,4空闲)
    e 扩展分区 (逻辑分区容器)
    选择 (默认 p):

    将使用默认回应 p。
    分区号 (1-4, 默认 1):
    第一个扇区 (2048-30318591, 默认 2048):
    上个扇区,+sectors 或 +size{K,M,G,T,P} (2048-30318591, 默认 30318591):

    创建了一个新分区 1,类型为“Linux”,大小为 14.5 GiB。

    命令(输入 m 获取帮助): t
    已选择分区 1
    Hex 代码(输入 L 列出所有代码): L

    0 空 24 NEC DOS 81 Minix / 旧 Linu bf Solaris
    1 FAT12 27 隐藏的 NTFS Win 82 Linux swap / So c1 DRDOS/sec (FAT-
    2 XENIX root 39 Plan 9 83 Linux c4 DRDOS/sec (FAT-
    3 XENIX usr 3c PartitionMagic 84 OS/2 隐藏 或 In c6 DRDOS/sec (FAT-
    4 FAT16 <32M 40 Venix 80286 85 Linux 扩展 c7 Syrinx
    5 扩展 41 PPC PReP Boot 86 NTFS 卷集 da 非文件系统数据
    6 FAT16 42 SFS 87 NTFS 卷集 db CP/M / CTOS / .
    7 HPFS/NTFS/exFAT 4d QNX4.x 88 Linux 纯文本 de Dell 工具
    8 AIX 4e QNX4.x 第2部分 8e Linux LVM df BootIt
    9 AIX 可启动 4f QNX4.x 第3部分 93 Amoeba e1 DOS 访问
    a OS/2 启动管理器 50 OnTrack DM 94 Amoeba BBT e3 DOS R/O
    b W95 FAT32 51 OnTrack DM6 Aux 9f BSD/OS e4 SpeedStor
    c W95 FAT32 (LBA) 52 CP/M a0 IBM Thinkpad 休 ea Rufus 对齐
    e W95 FAT16 (LBA) 53 OnTrack DM6 Aux a5 FreeBSD eb BeOS fs
    f W95 扩展 (LBA) 54 OnTrackDM6 a6 OpenBSD ee GPT
    10 OPUS 55 EZ-Drive a7 NeXTSTEP ef EFI (FAT-12/16/
    11 隐藏的 FAT12 56 Golden Bow a8 Darwin UFS f0 Linux/PA-RISC
    12 Compaq 诊断 5c Priam Edisk a9 NetBSD f1 SpeedStor
    14 隐藏的 FAT16 <3 61 SpeedStor ab Darwin 启动 f4 SpeedStor
    16 隐藏的 FAT16 63 GNU HURD 或 Sys af HFS / HFS+ f2 DOS 次要
    17 隐藏的 HPFS/NTF 64 Novell Netware b7 BSDI fs fb VMware VMFS
    18 AST 智能睡眠 65 Novell Netware b8 BSDI swap fc VMware VMKCORE
    1b 隐藏的 W95 FAT3 70 DiskSecure 多启 bb Boot Wizard 隐 fd Linux raid 自动
    1c 隐藏的 W95 FAT3 75 PC/IX bc Acronis FAT32 L fe LANstep
    1e 隐藏的 W95 FAT1 80 旧 Minix be Solaris 启动 ff BBT
    Hex 代码(输入 L 列出所有代码): b
    已将分区“Linux”的类型更改为“W95 FAT32”。

    命令(输入 m 获取帮助): p
    Disk /dev/sdc:14.5 GiB,15523119104 字节,30318592 个扇区
    单元:扇区 / 1 * 512 = 512 字节
    扇区大小(逻辑/物理):512 字节 / 512 字节
    I/O 大小(最小/最佳):512 字节 / 512 字节
    磁盘标签类型:dos
    磁盘标识符:0xcd48578f

    设备 启动 起点 末尾 扇区 大小 Id 类型
    /dev/sdc1 2048 30318591 30316544 14.5G b W95 FAT32

    命令(输入 m 获取帮助): w
    分区表已调整。
    将调用 ioctl() 来重新读分区表。
    正在同步磁盘。
  • 格式化TF卡:

    1
    2
    zhengk@ubuntu:/tmp$ sudo mkfs.vfat /dev/sdc1
    mkfs.fat 4.1 (2017-01-24)

    格式化为msdos格式。

  • 导入镜像文件:

    1
    2
    3
    4
    zhengk@ubuntu:/tmp$ sudo dd bs=1M if=2019-04-08-raspbian-stretch.img of=/dev/sdc 
    记录了3320+0 的读入
    记录了3320+0 的写出
    3481272320 bytes (3.5 GB, 3.2 GiB) copied, 331.952 s, 10.5 MB/s

    注意:可通过另外开一个shell窗口,输入如下命令打印导入进度:

    1
    sudo watch -n 5 pkill -USR1 ^dd$

    此时,原导入shell窗口会每隔5秒打印出如下进度:

    1
    2
    3
    4
    5
    记录了1640+0 的读入
    记录了1640+0 的写出
    1719664640 bytes (1.7 GB, 1.6 GiB) copied, 79.5407 s, 21.6 MB/s
    记录了1741+0 的读入
    记录了1741+0 的写出
  • 将TF卡插回至树莓派即可。

导出系统备份文件

  • 将树莓派的TF卡通过读卡器连接电脑

  • 查看TF卡所在的盘符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    zhengk@ubuntu:/tmp$ sudo fdisk -l
    Disk /dev/sdc:14.5 GiB,15523119104 字节,30318592 个扇区
    单元:扇区 / 1 * 512 = 512 字节
    扇区大小(逻辑/物理):512 字节 / 512 字节
    I/O 大小(最小/最佳):512 字节 / 512 字节
    磁盘标签类型:dos
    磁盘标识符:0xcd48578f

    设备 启动 起点 末尾 扇区 大小 Id 类型
    /dev/sdc1 8192 96042 87851 42.9M c W95 FAT32 (LBA)
    /dev/sdc2 98304 6799359 6701056 3.2G 83 Linux
  • 弹出TF卡所在的盘符:

    这里unmount操作,是为了防止挂载之后存在其他进程访问而导致后续操作失败,所以必须先进行unmount操作。

    1
    2
    zhengk@ubuntu:/tmp$ umount /dev/sdc1
    zhengk@ubuntu:/tmp$ umount /dev/sdc2
  • 导出镜像文件到当前目录即可

    1
    2
    3
    4
    zhengk@ubuntu:/tmp$ sudo dd if=/dev/sdc of=raspberrypi.img
    记录了30318592+0 的读入
    记录了30318592+0 的写出
    15523119104 bytes (16 GB, 14 GiB) copied, 212.231 s, 73.1 MB/s

    注意:过程中可使用如下命令通过查看文件大小变化来感知进度:

    1
    2
    3
    4
    5
    watch -d -n 5 ls -lh ~/tmp/
    Every 5.0s: ls -lh /tmp/ ubuntu: Sat Apr 13 17:30:02 2019

    总用量 18G
    -rw-r--r-- 1 root root 15G 4月 13 17:29 raspberrypi.img

系统备份文件压缩

  • 下载树莓派镜像压缩工具:

    1
    wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
  • 设置可执行权限:

    1
    chmod +x pishrink.sh
  • 将工具添加到环境变量

    1
    sudo mv pishrink.sh /usr/local/bin
  • 对备份的镜像文件进行压缩

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sudo pishrink.sh raspberrypi.img
    rootfs: 92570/209664 files (0.1% non-contiguous), 679211/837632 blocks
    resize2fs 1.44.1 (24-Mar-2018)
    resize2fs 1.44.1 (24-Mar-2018)
    Resizing the filesystem on /dev/loop12 to 813317 (4k) blocks.
    Begin pass 3 (max = 26)
    Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    The filesystem on /dev/loop12 is now 813317 (4k) blocks long.

    Shrunk raspberrypi.img from 15G to 3.2G

    可以看到这里已经将备份文件从15G压缩到了3.2G。不过,这里的压缩处理,会直接修改备份的镜像文件,而不是另外生成一个压缩版本的镜像文件,可先自行备份原镜像文件。

注意:

  • 这个压缩工具是通过shell脚本实现的,仅支持linux操作系统,在MacOS下会因为没有parted工具而失败。

  • 如果你的linux系统是中文本,那么可能会因为字符的问题导致运行报错:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ sudo pishrink.sh raspberry-image-2.0-保留root权限.img 
    Creating new /etc/rc.local
    /dev/loop7:101933/971040 文件(0.3% 为非连续的), 712924/3872384 块
    resize2fs 1.44.1 (24-Mar-2018)
    /usr/local/bin/pishrink.sh: 行 151: [[: 预计文件系统的最小尺寸:770851: 语法错误: 需要操作数 (错误符号是 "预计文件系统的最小尺寸:770851")
    /usr/local/bin/pishrink.sh: 行 157: 3872384 - 预计文件系统的最小尺寸:770851: 语法错误: 需要操作数 (错误符号是 "预计文件系统的最小尺寸:770851")
    resize2fs 1.44.1 (24-Mar-2018)
    resize2fs: 无效的新大小: 预计文件系统的最小尺寸:770851

    ERROR: resize2fs failed...
    mount: /tmp/tmp.Y7YrhlFNO7: can't read superblock on /dev/loop7.
    mv: 无法获取'/tmp/tmp.Y7YrhlFNO7/etc/rc.local.bak' 的文件状态(stat): 没有那个文件或目录
    umount: /tmp/tmp.Y7YrhlFNO7: not mounted.
    losetup: /dev/loop7:断开失败: 没有那个设备或地址

    解决方法为,指定英文语言运行,命令如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    zhengk@ubuntu:/tmp$ sudo LANG=en_US pishrink.sh raspberrypi.img 
    rootfs: 92570/209664 files (0.1% non-contiguous), 679211/837632 blocks
    resize2fs 1.44.1 (24-Mar-2018)
    resize2fs 1.44.1 (24-Mar-2018)
    Resizing the filesystem on /dev/loop12 to 813317 (4k) blocks.
    Begin pass 3 (max = 26)
    Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    The filesystem on /dev/loop12 is now 813317 (4k) blocks long.

    Shrunk raspberrypi.img from 15G to 3.2G

    可参考issue:https://github.com/Drewsif/PiShrink/issues/85

系统备份文件恢复

系统备份文件的恢复与导入系统镜像文件一样,使用备份的镜像导入即可。

其他

  • dd命令:

    上述在进行导入、导出时都用到了dd命令,这是在LiunxUnix下通用的命令,用于指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。

    可参考:https://baike.baidu.com/item/dd命令

  • pishrink.sh

    该备份文件压缩脚本是在Github上开源的工具,可访问https://github.com/Drewsif/PiShrink查看更多信息。

  • fdisk命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    欢迎使用 fdisk (util-linux 2.31.1)。
    更改将停留在内存中,直到您决定将更改写入磁盘。
    使用写入命令前请三思。


    命令(输入 m 获取帮助): m

    帮助:

    DOS (MBR)
    a 开关 可启动 标志
    b 编辑嵌套的 BSD 磁盘标签
    c 开关 dos 兼容性标志

    常规
    d 删除分区
    F 列出未分区的空闲区
    l 列出已知分区类型
    n 添加新分区
    p 打印分区表
    t 更改分区类型
    v 检查分区表
    i 打印某个分区的相关信息

    杂项
    m 打印此菜单
    u 更改 显示/记录 单位
    x 更多功能(仅限专业人员)

    脚本
    I 从 sfdisk 脚本文件加载磁盘布局
    O 将磁盘布局转储为 sfdisk 脚本文件

    保存并退出
    w 将分区表写入磁盘并退出
    q 退出而不保存更改

    新建空磁盘标签
    g 新建一份 GPT 分区表
    G 新建一份空 GPT (IRIX) 分区表
    o 新建一份的空 DOS 分区表
    s 新建一份空 Sun 分区表