COREELEC系统在Linux下迁移到另外一张SD卡

本文详细记录了如何在Linux环境下,使用qemu-img、dd、tar和gzip等工具备份和迁移COREELEC系统在SD卡上的内容。过程中涉及qemu-img的转换与压缩、dd命令的使用、tar备份的注意事项以及gzip压缩。最终成功将系统从32GB SD卡迁移到4GB SD卡,并解决了备份和恢复过程中的各种问题,包括分区信息的备份和恢复。
摘要由CSDN通过智能技术生成

需求

机顶盒之前的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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值