COREELEC系统在Linux下迁移到另外一张SD卡
需求
机顶盒之前的COREELEC系统在一张32GB的SD卡上,最近找到1张4GB卡,考虑到该系统只需要1GB就足够了,因此计划拷贝到新卡。之前折腾过一些配置,不想重新配置,关键是一直想搞清楚别人是怎么制作多分区的镜像。
需要备份的SD磁盘内容
root@xyhp:~# fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 29.1 GiB, 31268536320 bytes, 61071360 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: 0x3c4e2362
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 * 8192 1056767 1048576 512M c W95 FAT32 (LBA)
/dev/mmcblk0p2 1056768 2105343 1048576 512M 83 Linux
xxyy@xyhp:~/Desktop$ df -h /media/xxyy/{CO*,S*}
Filesystem Size Used Avail Use% Mounted on
/dev/mmcblk0p1 511M 213M 299M 42% /media/xxyy/COREELEC
/dev/mmcblk0p2 488M 5.9M 447M 2% /media/xxyy/STORAGE
操作环境
root@xyhp:~# dd --version
dd (coreutils) 8.30
Copyright (C) 2018 Free Software Foundation, Inc.
许可证 GPLv3+:GNU 通用公共许可证第 3 版或更新版本<https://gnu.org/licenses/gpl.html>。
本软件是自由软件:您可以自由修改和重新发布它。
在法律范围内没有其他保证。
由Paul Rubin、David MacKenzie 和Stuart Kemp 编写。
root@xyhp:~# cat /etc/os-release
PRETTY_NAME="UnionTech OS Desktop 20 Home"
NAME="uos"
VERSION_ID="20 Home"
VERSION="20 Home"
ID=uos
HOME_URL="https://www.chinauos.com/"
BUG_REPORT_URL="http://bbs.chinauos.com"
root@xyhp:~#
xxyy@xyhp:~$ uname -rp
5.7.7-amd64-desktop unknown
迁移方案分析
1、qemu-img命令
2、dd命令
3、mkisofs命令
4、tar命令
1、qemu-img 备份
qemu-img dd命令:
root@xyhp:~# qemu-img dd -O qcow2 bs=1m if=/dev/mmcblk0p1 of=COREELEC.qcow2
文件完全没有压缩
root@xyhp:~# du -sm CO*
513 COREELEC.qcow2
root@xyhp:~# qemu-img info COREELEC.qcow2
image: COREELEC.qcow2
file format: qcow2
virtual size: 512M (536870912 bytes)
disk size: 512M
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
root@xyhp:~# ll COREELEC.qcow2
-rw-r--r-- 1 root root 537198592 7月 2 14:34 COREELEC.qcow2
还不能直接挂载
root@xyhp:~# mount COREELEC.qcow2 /mnt/a
mount: /mnt/a: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.
这还不如直接dd备份。
root@xyhp:~# rm COREELEC.qcow2
qemu-img convert命令
命令格式:
convert [–object objectdef] [–image-opts] [–target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 […]] output_filename
瞬间完成
root@xyhp:~# qemu-img convert -O qcow2 /dev/mmcblk0p1 COREELEC2.qcow2
root@xyhp:~# qemu-img info COREELEC2.qcow2
image: COREELEC2.qcow2
file format: qcow2
virtual size: 512M (536870912 bytes)
disk size: 512M
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
root@xyhp:~# file COREELEC2.qcow2
COREELEC2.qcow2: QEMU QCOW Image (v3), 536870912 bytes
增加-c参数,压缩不明显
root@xyhp:~# qemu-img convert -c -O qcow2 /dev/mmcblk0p1 COREELEC2.qcow2
root@xyhp:~# qemu-img info COREELEC2.qcow2
image: COREELEC2.qcow2
file format: qcow2
virtual size: 512M (536870912 bytes)
disk size: 490M
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
root@xyhp:~#
qemu-img convert 还原
qemu-img convert -c -O qcow /dev/mmcblk0p1 COREELEC3.qcow2
时间更长,基本上没有压缩 disk size: 502M
root@xyhp:~# qemu-img convert -O raw COREELEC3.qcow2 COREELEC3.raw
root@xyhp:~# qemu-img info COREELEC3.raw
image: COREELEC3.raw
file format: raw
virtual size: 512M (536870912 bytes)
disk size: 511M
还原为裸设备后,可以正常挂载
root@xyhp:~# file COREELEC3.raw
COREELEC3.raw: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "mkfs.fat", sectors/cluster 8, Media descriptor 0xf8, sectors/track 16, heads 4, hidden sectors 8192, sectors 1048576 (volumes > 32 MB), FAT (32 bit), sectors/FAT 1024, reserved 0x1, serial number 0xc176bc81, unlabeled
root@xyhp:~# mount COREELEC3.raw /mnt/a
root@xyhp:~# ls /mnt/a
aml_autoscript cfgload device_trees dtb.xml kernel.img.md5 resolution.ini SYSTEM.md5
Android config.ini dtb.img kernel.img LOST.DIR SYSTEM 'System Volume Information'
root@xyhp:~#
2、mkisofs未验证
xxyy@xyhp:~/Desktop$ mkisofs -h
bash: mkisofs: command not found
xxyy@xyhp:~/Desktop$ sudo apt search mkisofs
Password
[sudo] password for xxyy:
Verification successful
Sorting... Done
Full Text Search... Done
xorriso/unknown 1.5.0-1 amd64
command line ISO-9660 and Rock Ridge manipulation tool
安装命令:sudo apt install xorriso
还是不支持mkisofs命令,
xxyy@xyhp:~/Desktop$ xorr
xorrecord xorriso xorrisofs
xxyy@xyhp:~/Desktop$ xorriso -h 非常复杂的参数
xxyy@xyhp:~/Desktop$ xorrisofs --help
Usage: xorriso -as mkisofs [options] file...
Note: This is not mkisofs. See xorriso -help, xorriso -version, man xorrisofs
。。。。。。
3、tar备份
错误命令
居然报错
root@xyhp:~# tar -zcf /media/xxyy/COREELEC /media/xxyy/STORAGE COREELEC_STORAGE.tar.gz
tar: 从成员名中删除开头的“/”
tar (child): /media/xxyy/COREELEC:无法 open: 是一个目录
tar (child): Error is not recoverable: exiting now
tar: 从硬连接目标中删除开头的“/”
tar: /media/xxyy/COREELEC:无法 write: 断开的管道
tar: Child returned status 2
tar: Error is not recoverable: exiting now
root@xyhp:~# cd /media/xxyy/
root@xyhp:/media/xxyy# ls
CCCOMA_X64F COREELEC data efi STORAGE Windows
root@xyhp:/media/xxyy#
正确备份
压缩后的目标文件要放在最前面
root@xyhp:~# tar -zcf ~/COREELEC_STORAGE.tar.gz /media/xxyy/COREELEC /media/xxyy/STORAGE
tar: 从成员名中删除开头的“/”
tar: 从硬连接目标中删除开头的“/”
root@xyhp:~# du -sm C*gz
191 COREELEC_STORAGE.tar.gz
root@xyhp:~#
使用绝对路径备份的文件,解压后会生成media/xxyy/的目录前缀。
尽量进入目录再压缩,即:
cd /media/xxyy/
tar -zcf ~/COREELEC_STORAGE.tar.gz COREELEC STORAGE
4、dd和gzip命令通过管道符压缩
先用文件验证命令和语法,压缩和解压缩正常。
root@xyhp:~# cp gparted_details-seagate-sshd500gb.htm a
root@xyhp:~# dd if=a |gzip > a.zip
记录了11+1 的读入
记录了11+1 的写出
5738 bytes (5.7 kB, 5.6 KiB) copied, 3.1677e-05 s, 181 MB/s
root@xyhp:~# file a.zip
a.zip: gzip compressed data, last modified: Fri Jul 2 08:07:10 2021, from Unix, original size 5738
前面的压缩时的后缀名不匹配,导致无法解压
root@xyhp:~# gzip -d a.zip
gzip: a.zip: unknown suffix -- ignored
root@xyhp:~# gzip -d a
gzip: a.gz: No such file or directory
root@xyhp:~# mv a.zip a.gz
root@xyhp:~# gzip -d a
root@xyhp:~# vi a
用diff命令验证,恢复的文件和源文件相同
root@xyhp:~# diff a gparted_details-seagate-sshd500gb.htm
root@xyhp:~#
实战备份
备份2个分区到1个文件
由于SD卡总共32G,实际2个分区只使用了1G,需要用bs和count指定备份的大小(多加了1M),避免浪费时间。
status可以在备份时输出进度信息
dd没有指定of参数会输出到屏幕,通过管道符引入到gzip的文件中
root@xyhp:~# dd if=/dev/mmcblk0 bs=1M count=1025 status=progress | gzip > sdcard_bak1G.img.gz
1053818880 bytes (1.1 GB, 1005 MiB) copied, 48 s, 22.0 MB/s
记录了1025+0 的读入
记录了1025+0 的写出
1074790400 bytes (1.1 GB, 1.0 GiB) copied, 48.9189 s, 22.0 MB/s
这张SD卡读取速度22MB/s
root@xyhp:~# du -sm sdcard_bak1G.img.gz
490 sdcard_bak1G.img.gz
root@xyhp:~# file sdcard_bak1G.img.gz
sdcard_bak1G.img.gz: gzip compressed data, last modified: Fri Jul 2 08:23:22 2021, from Unix, original size 1074790400
root@xyhp:~#
压缩后有490M,和前面qemu-img大小差不多,比期望的文件大了很多。
root@xyhp:~# du -sm /media/xxyy/COREELEC
213 /media/xxyy/COREELEC
root@xyhp:~# du -sm /media/xxyy/STORAGE
6 /media/xxyy/STORAGE
弄个目录再压缩,没有用
root@xyhp:~# mkdir a
root@xyhp:~# mv sdcard_bak1G.img.gz a
root@xyhp:~# tar -zcf a.tar.gz a
root@xyhp:~# du -sm a.tar.gz
490 a.tar.gz
root@xyhp:~#
更换新SD卡
卸载文件系统
umount /media/xxyy/COREELEC
umount /media/xxyy/STORAGE
更换4GB的SD卡
无法识别新的SD卡,插拔几次也不行;dmesg有io错误;重启进入win10读取文件支持,fat32格式。
重启到UOS统信linux
root@xyhp:/home/xxyy/Desktop# fdisk -l
...
Disk /dev/mmcblk0: 3.7 GiB, 3984588800 bytes, 7782400 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: 0x7eab5fae
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 2048 7782399 7780352 3.7G b W95 FAT32
root@xyhp:/home/xxyy/Desktop#
已自动挂载
root@xyhp:~# lsblk -p
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
/dev/mmcblk0 179:0 0 3.7G 0 disk
└─/dev/mmcblk0p1 179:1 0 3.7G 0 part /media/xxyy/sd
root@xyhp:~# lsblk -pf
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
/dev/mmcblk0
└─/dev/mmcblk0p1 vfat sd 0006-99F0 3.7G 1% /media/xxyy/sd
卸载
root@xyhp:~# umount /media/xxyy/sd
实战恢复
正确解压
root@xyhp:~# gzip -dc sdcard_bak1G.img.gz | dd of=/dev/mmcblk0 bs=1M conv=fsync status=progress
987922432 bytes (988 MB, 942 MiB) copied, 4 s, 247 MB/s 4秒读取完毕,卡在这里
0+32479 records in
0+32479 records out
1074790400 bytes (1.1 GB, 1.0 GiB) copied, 213.427 s, 5.0 MB/s
root@xyhp:~#
root@xyhp:~# sync 刷新缓存到SD卡,有的系统不会刷新到磁盘/SD卡
验证数据恢复正常
root@xyhp:~# mount /dev/mmcblk0p1 /mnt
root@xyhp:~# ls /mnt
aml_autoscript cfgload device_trees dtb.xml kernel.img.md5 resolution.ini SYSTEM.md5
Android config.ini dtb.img kernel.img LOST.DIR SYSTEM ‘System Volume Information’
root@xyhp:~# umount /mnt
root@xyhp:~# mount /dev/mmcblk0p2 /mnt
root@xyhp:~# ls /mnt
backup lost+found music pictures screenshots tvshows videos
root@xyhp:~#
至此内容迁移完成。
实际上,新的SD卡在新机顶盒上能启动系统,但无法连接网络,这是另外的问题,单独写一篇文章。
新SD卡实际还剩余约3GB的空间没有分区,可以在不丢失数据的情况下扩容,单独写一篇文章。
总结:
qemu-img convert可以实现备份,压缩比率小。
dd加gzip或者直接dd可以备份恢复,gzip的压缩比率也小。
压缩比小的问题:可能是本身的文件已经是压缩过的。
mkisofs和tar只能对文件进行备份,无法备份分区信息。
附录
这里记录一下自己走过的弯路。相对独立的一章。
备份的SD卡信息:
SD卡信息
fdisk -l
Disk /dev/mmcblk0: 3.7 GiB, 3984588800 bytes, 7782400 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: 0xe6709663
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 * 8192 1056767 1048576 512M c W95 FAT32 (LBA)
/dev/mmcblk0p2 1056768 2105343 1048576 512M 83 Linux
备份方法:
root@xyhp:~# dd if=/dev/mmcblk0 bs=1M count=1025 status=progress | gzip > sdcard_bak1G.img.gz
恢复方法,写入新的SD卡
弯路1:写错of文件
备份时是备份的整个SD卡(disk),解压时却使用了SD卡其中的一个分区。
root@xyhp:~# gzip -c sdcard_bak1G.img.gz | dd of=/dev/mmcblk0p1 bs=1M conv=fsync status=progress
512853876 bytes (513 MB, 489 MiB) copied, 11 s, 44.7 MB/s
卡在这里了。
0+30536 records in
0+30536 records out
512853876 bytes (513 MB, 489 MiB) copied, 104.173 s, 4.9 MB/s
分区无变化,/dev/mmcblk0p1和/dev/mmcblk0都无法mount。
前面of设备名应该去掉p1,不指定分区,应该指定整个硬盘
弯路2:解压参数错误,没有加-d表示解压
root@xyhp:~# gzip -c sdcard_bak1G.img.gz | dd of=/dev/mmcblk0 bs=1M conv=fsync status=progress
479346688 bytes (479 MB, 457 MiB) copied, 10 s, 47.9 MB/s
0+30343 records in
0+30343 records out
512853876 bytes (513 MB, 489 MiB) copied, 107.916 s, 4.8 MB/s
写入只有513M,分区都没有了。
root@xyhp:~# fdisk -l
...
Disk /dev/mmcblk0: 3.7 GiB, 3984588800 bytes, 7782400 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
root@xyhp:~#
头晕了,解压没有加 -d参数
-c, --stdout write on standard output, keep original files unchanged
-d, --decompress decompress
弯路2的验证:手工重新创建分区
这里实际上没有作用,前面缺少-d解压,写到SD卡的数据是错误的(根本没有解压),重新创建分区也毫无意义。
只是记录一下创建分区的方法。
root@xyhp:~# fdisk /dev/mmcblk0
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (1-4, default 1):
First sector (2048-7782399, default 2048): 8192
Last sector, +/-sectors or +/-size{K,M,G,T,P} (8192-7782399, default 7782399): 1056767
Created a new partition 1 of type 'Linux' and of size 512 MiB.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (2048-7782399, default 2048): 1056768
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1056768-7782399, default 7782399): 2105343
Created a new partition 2 of type 'Linux' and of size 512 MiB.
Command (m for help):
修改分区格式
Command (m for help): t
Partition number (1,2, default 2): 1
Hex code (type L to list all codes): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Command (m for help):
修改启动标记,这个是ARM的安卓用的系统,不设置也没有关系。
Command (m for help): a
Partition number (1,2, default 2): 1
The bootable flag on partition 1 is enabled now.
检查分区,和前面的SD卡完全相同。
Command (m for help): p
写入分区信息
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
root@xyhp:~#
root@xyhp:~# mount /dev/mmcblk0p1 /mnt
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/mmcblk0p1, missing codepage or helper program, or other error.
仍然无法挂载。
正确解压
前面的分区表是手工创建的,破坏分区表和数据后,便于验证
root@xyhp:~# dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=2
2+0 records in
2+0 records out
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.000895927 s, 2.3 GB/s
root@xyhp:~# fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 3.7 GiB, 3984588800 bytes, 7782400 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
用正确命令解压。
root@xyhp:~# gzip -dc sdcard_bak1G.img.gz | dd of=/dev/mmcblk0 bs=1M conv=fsync status=progress
997556224 bytes (998 MB, 951 MiB) copied, 4 s, 249 MB/s
0+32507 records in
0+32507 records out
1074790400 bytes (1.1 GB, 1.0 GiB) copied, 213.589 s, 5.0 MB/s
验证没有问题:正确挂载,ls文件正确。
参考文章
1、在linux上制作树莓派最小img镜像
xianxujiang 2018-06-03 01:30:37 6721 收藏 16
————————————————
版权声明:本文为CSDN博主「xianxujiang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013451404/article/details/80552765
2、Installing operating system images on Linux
https://www.raspberrypi.org/documentation/installation/installing-images/linux.md
unzip -p 2021-05-07-raspios-buster-armhf.zip | sudo dd of=/dev/sdX bs=4M conv=fsync