基于DitePi系统(Debian)的NanoPi2 Fire 开发板系统备份与还原

时间:2024-04-04 15:46:56

    几年前购买的NanoPi2 Fire开发板,当时没有时间摆弄,最近翻出来,准备做一个web 服务器用来调试程序,也可以做一个内部的文件服务器,挂上一个大硬盘存放各种文件。

基于DitePi系统(Debian)的NanoPi2 Fire 开发板系统备份与还原

1. DitePi系统刷写

    DietPi(http://www.dietpi.com/)是一个非常轻量级的debian系统,支持apt联网更新。在其官网上有各种开发板对应的img,NanoPi2 Fire开发板可以使用M2/T2的版本:

基于DitePi系统(Debian)的NanoPi2 Fire 开发板系统备份与还原

 

linux刷写T卡:

插入U盘,如果linux系统自动挂载了U盘,则需要先卸载掉。假设u盘为/dev/sdb, 挂载点为/mnt/usbx,要先执行:

    [email protected]:~$sudo umount  /mnt/usbx

然后执行写入img的命令

    [email protected]:~$sudo dd bs=4M if=DietPi_v6.14_NanoPiM2-ARMv7-Stretch.img of=/dev/sdb

window下刷写T卡:

直接使用win32diskimage软件进行刷写,不再复述。

建议使用8G的T卡,太小的话很多必备软件无法安装。

刷完后使用T卡开机可以进入DietPi的安装界面:

基于DitePi系统(Debian)的NanoPi2 Fire 开发板系统备份与还原

    刷入的系统是最小化系统,开机后请根据自己的需求设置下载软件更新,同时可以更新root密码。刷入系统后会有2个分区,boot分区和rootfs分区,其中rootfs分区是400多M,基本上已经满了(因为做img的时候需要能刷到各种容量的T卡中,自然只能做成最小容量的img),所以直接更新软件会出错,提示空间不足,此时需要修改分区表,把8G T卡的其它部分都找回来。

    在DietPi的配置界面上选择退出,不进行任何更新,回到命令行shell:

  a. df -h 查看启动盘里的挂载点
  b. fdisk /dev/mmcblk0
    命令:按p(打印所有分区,应该会看到2个分区,/dev/mmcblk0p2就是rootfs分区)

    命令:按d(删除分区2)
    命令:按p(打印所有分区,此时只有1个分区)
    命令:按n(添加分区)

      选择p (主分区) 于分区2
      选择2 第一空格输入原来分区2的开始位置
      最后的空格输入默认值

    命令:按p(打印所有分区,应该会看到新增的分区填满了整个T卡)
    命令:按w(保存)
  c. reboot 重启开发板
  d. resize2fs /dev/mmcblk0p2  重启后使用resize2fs来修复分区2,8G T卡耗时10秒左右,越大耗时越多。
    此时再用df -h查看分区大小,可以看到rootfs空间已经多出来很多。

    resize完T卡后,根据DitePi config的提示界面下载更新必要的系统软件,更新后rootfs会变大,我这里更新后,rootfs从400多M变到了1G多。

2. 备份T卡中的系统

    由于boot分区只有64M,rootfs有1G多,因此,预期从8G T卡中备份出的img文件大概也就1G多。并且备份出来的img,要能刷写到大于img文件大小的T卡中,然后正常启动系统。

    当前的环境是:
      电脑:lubuntu 18.10  Linux version 4.18.0-10-generic  64bit
      开发板:DietPi系统 Linux version 3.4.39-s5p4418 32bit

2.1 电脑上备份软件准备

    sudo apt-get install dump
    sudo apt-get install parted
    sudo apt-get install kpartx

2.2 首先在电脑上生成一个空的镜像文件

    [email protected]:~$sudo dd if=/dev/zero of=linux_bak.img bs=1048576 count=1200

    bs:1024*1024  → 1M

    count: 1200 所以总共1200M  → 1.2G

2.3 使用parted工具把空镜像分区

    先看一下T卡的分区信息:

[email protected]:~# fdisk -l
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: 0x5714d005

Device          Boot   Start     End       Sectors  Size      Id   Type
/dev/mmcblk0p1         2048      133119    131072    64M      83   Linux
/dev/mmcblk0p2         133120    13416000  13282881  6.3G     83   Linux
/dev/mmcblk0p3         13416448  15523839  2107392   1G       82   Linux swap / Solaris

    执行以下命令给空镜像分区:

    [email protected]:~$sudo parted linux_bak.img  --script -- mklabel msdos

    [email protected]:~$sudo parted linux_bak.img  --script -- mkpart primary ext4 2048s 133119s  #boot分区

    [email protected]:~$sudo parted linux_bak.img  --script -- mkpart primary ext4 133120s   -1     #rootfs分区

注意,boot分区是从第2048个Sector开始的,那么0-2047个Sector是做什么用的?是否需要备份?这个在后面会说明。

2.4 把镜像挂载到loop设备上并格式化

    [email protected]:~$sudo losetup -f
        返回/dev/loop0
    [email protected]:~$sudo  losetup  /dev/loop0  linux_bak.img
    [email protected]:~$sudo kpartx -av  /dev/loop0

    此时在/dev/mapper目录下会出现2个映射的设备loop0p1和loop0p2,这2个映射出来的设备就对应img文件里的2个分区

    [email protected]:~$echo y | sudo mkfs.ext4 -L boot -O ^metadata_csum -U fefadc12-19a0-0057-8159-b9aed3a0a533 /dev/mapper/loop0p1

    [email protected]:~$echo y | sudo mkfs.ext4 -L rootfs -O ^metadata_csum -U ff313567-e9f1-5a5d-9895-3ba130b4a864 /dev/mapper/loop0p2

    格式化这2个分区,里面彩色的参数非常重要:

    红色的 -L参数指明了分区的标签

    蓝色的 -O 参数表明要关掉文件系统的校验check_sum功能,因为DietPi的内核是3.4.39而电脑的内核是4.18.0,DietPi的系统并不支持metadata_csum功能,如果不去掉,做出来的img在启动的时候会报错:

基于DitePi系统(Debian)的NanoPi2 Fire 开发板系统备份与还原

    关于Metadata_Checksums更进一步的细节参考:
        https://blog.csdn.net/younger_china/article/details/22286377
        https://ext4.wiki.kernel.org/index.php/Ext4_Metadata_Checksums
        https://blog.csdn.net/P40814001/article/details/82892337?utm_source=blogxgwz9

    绿色的-U 参数指定分区的时候,给分区一个确定的UUID,如果不指定UUID,格式化后会有一个随机的UUID,跟备份系统/etc/fstab 挂载的分区UUID会不匹配,我省得修改fstab文件了,直接指定一下UUID即可。

2.5 使用dump命令备份T卡上的数据

先备份boot分区:

    [email protected]:~$sudo mkdir/mnt/bk_image
    [email protected]:~$sudo mount -t ext4 /dev/mapper/loop0p1 /mnt/bk_image #挂载img文件里的boot分区
    [email protected]:~$cd  /mnt/bk_image

    [email protected]:/mnt/bk_image$sudo dump -0uaf - /dev/sdb1 | sudo restore -rf -
    [email protected]:/mnt/bk_image$cd ~
    [email protected]:~$sudo umount /mnt/bk_image

再备份rootfs分区:

    [email protected]:~$sudo mount -t ext4 /dev/mapper/loop0p2 /mnt/bk_image #挂载img文件里的rootfs分区
    [email protected]:~$cd  /mnt/bk_image
    [email protected]:/mnt/bk_image$sudo dump -0uaf - /dev/sdb2 | sudo restore -rf -
    [email protected]:/mnt/bk_image$cd ~
    [email protected]:~$sudo umount /mnt/bk_image

2.6 清理环境 

    [email protected]:~$sudo rm -rf  /mnt/bk_image
    [email protected]:~$sudo kpartx -d  /dev/loop0
    [email protected]:~$sudo losetup -d /dev/loop0

2.7  备份bootloader

    前面几步已经把系统的数据都备份完成了,如果马上刷写生成的img文件,放到NanoPi2 Fire开发板上,是无法启动的,甚至连hdmi都没有输出信号。

    前面提到的0-2047扇区,现在要重点说明一下。目前无法启动系统,是由于引导程序没有备份出来,而引导程序就存储在前2048个扇区里。

    T卡上每个Sector(扇区)是512 bytes,前2048个扇区一共是512*2048=1048576 (1M bytes)存储空间。这1M空间约定是存储 MBR(Master Boot Record)第0个扇区和引导程序(1-2047扇区)的。我们之前格式化空img文件的时候,工具已经自动生成了MBR,而后面的引导程序却没有生成,使用二进制工具查看img文件的前1M数据,发现从512字节以后,全是0,所以导致刷写的系统无法正常引导。现在我们需要备份T卡里的引导程序,即第1-2047扇区里的数据到img文件里。使用如下命令:

    [email protected]:~$sudo dd bs=512 if=/dev/sdb of=linux_bak.img skip=1 seek=1 count=2047 conv=notrunc

        bs=512是以512个字节为单位,即1个扇区的大小为单位来进行复制操作

        skip=1 和seek=1的意思是跳过T卡的第一个扇区(MBR扇区),同时跳过img文件的第一个扇区(MBR扇区),向后复制2047个扇区到img文件里。

      conv=notrunc指明不要把已经生成好的img文件清空,没有这个参数,img文件中1M以后的数据都会被删掉。

3. 验证生成的img文件   

    插入另外一个大于1.2G的T卡到电脑的usb。如果T卡自动mount了,需要umount掉T卡的分区。然后刷入备份的img(假设T卡的设备是sdb):
        [email protected]:~$sudo dd bs=4M if= linux_bak.img of=/dev/sdb
    刷写1.2G的img,估计需要5-8分钟,shell命令行里没有提示,只有慢慢等到结束,备份越大刷写的时间越长。
    把刷完的T卡插入NanoPi2 Fire单板,加电后可以正常开机。备份方案成功。

备份的脚本(backupTF.sh)如下:

https://download.csdn.net/download/yellowhwb/11002803

注意脚本中的几个参数可能需要自修修改:

src_dev参数,根据自己linux电脑上的T卡设备修改

fefadc12-19a0-0057-8159-b9aed3a0a533 格式化时的uuid参数,要和T卡中/etc/fstab文件里的值一致。