几年前购买的NanoPi2 Fire开发板,当时没有时间摆弄,最近翻出来,准备做一个web 服务器用来调试程序,也可以做一个内部的文件服务器,挂上一个大硬盘存放各种文件。
1. DitePi系统刷写
DietPi(http://www.dietpi.com/)是一个非常轻量级的debian系统,支持apt联网更新。在其官网上有各种开发板对应的img,NanoPi2 Fire开发板可以使用M2/T2的版本:
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的安装界面:
刷入的系统是最小化系统,开机后请根据自己的需求设置下载软件更新,同时可以更新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在启动的时候会报错:
关于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文件里的值一致。