为什么 dd 给我的 SD 卡与其来源不同?

为什么 dd 给我的 SD 卡与其来源不同?

我有一张 32 Gb SD 卡,上面有我的操作系统(Raspberry Pi OS Buster),我希望使用标准进行备份dd,使用sudo dd if=/dev/sdb of=/mnt/toshiba2tb/pi20211217.img bs=1M

源SD卡在下面看起来完全没问题lsblk --fs

db
├─sdb1      vfat   RECOVERY 796F-5014
├─sdb2
├─sdb5      ext4   SETTINGS 3b129a7c-44fe-4062-8819-2be9ec66edea
├─sdb6      vfat   boot     3830-AECC
└─sdb7      ext4   root     92847503-3b1f-4e22-9fa0-f6794b8fed0c

映像完成后,我将其复制dd到(全新的)新卡上sudo dd if=/mnt/toshiba2tb/pi20211217.img of=/dev/sdb bs=1M,并获得一个不同的分区表,它甚至无法启动 RPi

sdb
├─sdb1      vfat   RECOVERY 796F-5014
└─sdb2

fdisk确认并报告和荒谬的2T分区......发生了什么事?

$ sudo fdisk -l /dev/sdb
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Invalid flag 0xffff of EBR (for partition 5) will be corrected by w(rite).
Disk /dev/sdb: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Disk model: LRWM04U
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: 0x000edc50

Device     Boot      Start        End    Sectors  Size Id Type
/dev/sdb1             8192    3781250    3773059  1.8G  e W95 FAT16 (LBA)
/dev/sdb2          3781251   60751871   56970621 27.2G  5 Extended
/dev/sdb5       4298748546 8593715840 4294967295    2T ff BBT

更多信息来自sudo /sbin/fdisk -l /mnt/toshiba2tb/pi20211217.img

$ sudo /sbin/fdisk -l /mnt/toshiba2tb/pi20211217.img
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Invalid flag 0xffff of EBR (for partition 5) will be corrected by w(rite).
Disk /mnt/toshiba2tb/pi20211217.img: 29 GiB, 31104958464 bytes, 60751872 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: 0x000edc50

Device                          Boot      Start        End    Sectors  Size Id Type
/mnt/toshiba2tb/pi20211217.img1            8192    3781250    3773059  1.8G  e W95 FAT16 (LBA)
/mnt/toshiba2tb/pi20211217.img2         3781251   60751871   56970621 27.2G  5 Extended
/mnt/toshiba2tb/pi20211217.img5      4298748546 8593715840 4294967295    2T ff BBT

我还尝试了dd_rescue一个新的图像文件,似乎直到最后都没有错误。

$ sudo dd_rescue /dev/sdb /mnt/toshiba2tb/pi20211217.rescue.img
dd_rescue: (info) expect to copy 30375936kB from /dev/sdb
dd_rescue: (info): ipos:  30375936.0k, opos:  30375936.0k, xferd:  30375936.0k
                   errs:      0, errxfer:         0.0k, succxfer:  30375936.0k
             +curr.rate:    10374kB/s, avg.rate:    20375kB/s, avg.load: 21.2%
             >----------------------------------------.<  99%  ETA:  0:00:00
dd_rescue: (info): read /dev/sdb (30375936.0k): EOF
dd_rescue: (info): Summary for /dev/sdb -> /mnt/toshiba2tb/pi20211217.rescue.img:
dd_rescue: (info): ipos:  30375936.0k, opos:  30375936.0k, xferd:  30375936.0k
                   errs:      0, errxfer:         0.0k, succxfer:  30375936.0k
             +curr.rate:        0kB/s, avg.rate:    20312kB/s, avg.load: 21.1%
             >----------------------------------------.<  99%  ETA:  0:00:00

不幸的是,获得的文件仍然显示出损坏的迹象

$ sudo /sbin/fdisk -l /mnt/toshiba2tb/pi20211217.rescue.img
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Invalid flag 0xffff of EBR (for partition 5) will be corrected by w(rite).
Disk /mnt/toshiba2tb/pi20211217.rescue.img: 29 GiB, 31104958464 bytes, 60751872 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: 0x000edc50

Device                                 Boot      Start        End    Sectors  Size Id Type
/mnt/toshiba2tb/pi20211217.rescue.img1            8192    3781250    3773059  1.8G  e W95 FAT16 (LBA)
/mnt/toshiba2tb/pi20211217.rescue.img2         3781251   60751871   56970621 27.2G  5 Extended
/mnt/toshiba2tb/pi20211217.rescue.img5      4298748546 8593715840 4294967295    2T ff BBT

只是为了检查,我确实刷新了此映像,它与所有其他映像具有相同的问题,启动找不到“设置”分区并永远挂在那里......

假设这可能只是一个分区表问题,我已将原始 SD 的分区表转储到使用sfdisk -d /dev/sdb > pi.partitiontable.它打印出一些有意义的东西

$ cat  pi.partitiontable
label: dos
label-id: 0x000edc50
device: /dev/sdb
unit: sectors

/dev/sdb1 : start=        8192, size=     3773059, type=e
/dev/sdb2 : start=     3781251, size=    56970621, type=5
/dev/sdb5 : start=     3784704, size=       65534, type=83
/dev/sdb6 : start=     3850240, size=      147454, type=c
/dev/sdb7 : start=     3997696, size=    56754176, type=83

然后我将此分区表复制到新复制的 SD 卡上, $ sudo sfdisk /dev/sdb < pi.partitiontable这给了

Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Ignoring extra data in partition table 5.
Invalid flag 0xffff of EBR (for partition 5) will be corrected by w(rite).
Checking that no-one is using this disk right now ... OK

Disk /dev/sdb: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Disk model: LRWM04U
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: 0x000edc50

Old situation:

Device     Boot      Start        End    Sectors  Size Id Type
/dev/sdb1             8192    3781250    3773059  1.8G  e W95 FAT16 (LBA)
/dev/sdb2          3781251   60751871   56970621 27.2G  5 Extended
/dev/sdb5       4298748546 8593715840 4294967295    2T ff BBT

>>> Script header accepted.                                                                                                                                                                            >>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Created a new DOS disklabel with disk identifier 0x000edc50.
/dev/sdb1: Created a new partition 1 of type 'W95 FAT16 (LBA)' and of size 1.8 GiB.
Partition #1 contains a vfat signature.
/dev/sdb2: Created a new partition 2 of type 'Extended' and of size 27.2 GiB.
/dev/sdb3: Created a new partition 5 of type 'Linux' and of size 32 MiB.
/dev/sdb6: Sector 3850240 is already allocated.
Created a new partition 6 of type 'W95 FAT32 (LBA)' and of size 72 MiB.
/dev/sdb7: Sector 3997696 is already allocated.
Created a new partition 7 of type 'Linux' and of size 27.1 GiB.
/dev/sdb8: Done.

New situation:
Disklabel type: dos
Disk identifier: 0x000edc50

Device     Boot   Start      End  Sectors  Size Id Type
/dev/sdb1          8192  3781250  3773059  1.8G  e W95 FAT16 (LBA)
/dev/sdb2       3781251 60751871 56970621 27.2G  5 Extended
/dev/sdb5       3784704  3850237    65534   32M 83 Linux
/dev/sdb6       3852286  3999739   147454   72M  c W95 FAT32 (LBA)
/dev/sdb7       4001788 60751871 56750084 27.1G 83 Linux

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

使用此卡时,启动会抱怨设置分区已损坏,因此要求重新安装操作系统。这与之前的错误不同,可能是由于(我猜测)我从旧卡上获取并复制到新卡上的分区表存在一些未对齐或轻微不兼容。我仍然想知道这种方法是否可行,也许可以对分区表进行一些调整......

答案1

fdisk -l图像上的输出表明您的图像很差;你可以使用任何读卡器将其写入任意数量的 SD 卡,但你总是会得到不好的结果。

您需要重新读取图像,最好使用能够明确告诉您何时无法正确读取卡片的工具;例如

ddrescue /dev/sdb /mnt/toshiba2tb/pi20211217.img

答案2

on的扇区数sdb5为4294967295 = 0xffffffff,分区类型ID也为0xff。还有Invalid flag 0xffff of EBR (for partition 5) will be corrected by w(rite)错误信息。

这看起来像是 SD 卡上的写入错误:不知何故,本应存在的实际数据字节已被全 1 字节替换。

第二张卡片的尺寸为:

Disk /dev/sdb: 29.7 GiB, 31914983424 bytes, 62333952 sectors

您可能想使用Fight Flash Fraud 项目的 f3 工具验证第二张卡的实际容量。

如果您的卡是假卡,则错误可能是由于扩展分区表位于卡闪存芯片的实际容量之外,位于实际上未被任何闪存芯片覆盖的空地址空间中,因此实际上对于存储没有用处。任何数据。尝试读取此类地址空间通常只会产生全 1 字节。写入此类地址空间的任何数据都会立即丢失。

假冒存储卡通常声称其存储容量比实际容量大得多。卡开头的存储工作正常,看起来该卡可以用于休闲测试。但是,一旦您尝试使用更多容量,该卡就会开始产生错误,或者更阴险地忽略错误并返回无意义的数据。

在您的情况下,块 # 3781251 处的扩展分区表(即距离卡开头约 1.9 GB)已损坏的事实可能意味着假卡实际上具有不到 2 GiB 的实际存储容量,尽管它声称有 29.7 GiB。

答案3

例如,具有指定标称尺寸的 SD 卡和 USB 闪存盘

32 GB = 10^9 * 32 / 2^30 GiB approx= 29.8 GiB

有接近标称尺寸的各种尺寸。有些驱动器稍大,有些驱动器稍小(是的,尺寸过小,但也不算太小)。

不幸的是,也存在欺诈行为,驱动器比名义尺寸小得多。

  • 克隆时的一个严重问题是,您无法将具有使用整个驱动器的分区的驱动器克隆到稍小的驱动器。目标驱动器在字节级别必须至少具有相同的大小,例如通过

    lsblk -b
    
  • 当驱动器具有完全相同的大小时,克隆就很简单。

  • 如果有 MSDOS 分区表(有时称为 MBR),则克隆到更大的驱动器很简单。在这种情况下,您可以增加“最后”分区的大小以使用未分配的驱动器空间。

  • 当克隆到更大的驱动器时,如果有 GUID 分区表 (GPT),则需要额外的操作。驱动器尾部应该有一个备份分区表,可以用以下命令修复它gdisk。这可以通过 shellscript 自动化gpt-fix。此修复已内置于姆库斯布克隆图像文件时。修复后,您可以增加“最后一个”分区的大小以使用未分配的驱动器空间。

因此,在放弃目标驱动器之前,请检查其大小,如果可能,请获取不小于原始驱动器的目标驱动器。另一种方法是缩小原始驱动器上的最后一个分区,使其适合目标驱动器的大小。您可以用于gparted此目的。

如果是 GPT,请修复备份分区表。

相关内容