5

I have a 32GB SD Card that contains an Armbian installation for some pi gadget. I want to clone the content into a 16GB card. Using GParted, I shrank the partitions to be less than 16GB and here is the state of the SD Card as shown in fdisk. There are 2 partitions, one is the Armbian and the other one is an small FAT32 partition to share files with windows.

Disk /dev/sdk: 29,74 GiB, 31914983424 bytes, 62333952 sectors
Disk model: USB3.0 CRW-SD/MS
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: 0x22563e30

Device Boot Start End Sectors Size Id Type /dev/sdk1 8192 25690111 25681920 12,3G 83 Linux /dev/sdk2 25690112 26509311 819200 400M b W95 FAT32

Can you please tell me what would I need to do now to exactly clone what is on the card, including the boot partition? It is strange that the Armbian leaved 8129 sectors free, and calls it unpartitioned space, what is in that area?

If I do something like:

dd if=/dev/sdk of=/home/user/backup.iso

It will create an image with size 32GB.... but I want it to be limited to the last sector of /dev/sdk2.

fra-san
  • 10,205
  • 2
  • 22
  • 43
DEKKER
  • 948
  • 8
  • 20

2 Answers2

7

You could use the largest end sector for count:

dd bs=512 count=26509312 if=/dev/sdk of=devsdk.img

Or with a different blocksize:

dd bs=1M count=$((26509312*512)) iflag=count_bytes if=/dev/sdk of=devsdk.img

It is strange that the Armbian leaved 8129 sectors free, and calls it unpartitioned space, what is in that area?

For embedded devices, unpartitioned space can hold bootloaders and kernel images, or anything else really. But it could be as simple as alignment considerations.

frostschutz
  • 48,978
  • 1
    Is reading from a block device using dd with bs and count (without fullblock) never an issue, in contrast to, for instance, yes | dd bs=1M count=...)? – fra-san May 29 '21 at 11:12
  • for block devices, it's usually fine for bs=1M... but you can add fullblock to the iflag if you like... or use something else like head -c $((26509312*512)) /dev/thing > thing.img – frostschutz May 29 '21 at 11:40
  • 1
    A block size of 512 bytes for physical blocks of 4K is really inefficient. Increase your block size to (at least) 1M. Better, just use cat image > /dev/device – Chris Davies May 29 '21 at 12:26
  • @roaima: If you're not using O_DIRECT, the "block size" only means the size of your read and write system calls, so you're actually wasting CPU time (on syscall overhead, and on the kernel's block I/O layer doing merging of pending requests). Unless your device is really fast, you're probably not losing I/O throughput. bs=128k or 64k is often good: about half of L2 cache size is a good tradeoff of system-call overhead vs. getting cache hits in the kernel's copy_to_user / copy_from_user. (And perhaps small enough that it doesn't need much splitting into actual SATA or NVMe requests?) – Peter Cordes May 29 '21 at 22:12
  • 2
    @PeterCordes I don't know if Linux's I/O anticipation and scheduling has become faster, but when I benchmarked it a decade ago, it did make a small but measurable difference. cat was the winner for a different-disk copy. – Gilles 'SO- stop being evil' May 29 '21 at 23:09
  • @Gilles'SO-stopbeingevil': I'd certainly believe "small but measurable", e.g. because of better/worse HW prefetch. roaima's "really inefficient" comment seemed to imply that requests to the hardware device itself would be made as 512-byte reads or writes. For writes, that would imply an internal RMW to modify 512 bytes in a 4k HW sector, for each write, unless the device did internal write-combining. That would be a more than 8x slowdown (if that step was the original bottleneck), and that certainly doesn't happen. – Peter Cordes May 29 '21 at 23:15
4

Forget dd: it's hard to use reliably and somewhat slow. Despite a common myth, there's no magic in dd: the magic is in /dev/*.

To copy up to sector 26509311 in units of 512-bytes sector, use head. Remember to add 1 because sectors start at 0.

sudo head -c $(((26509311 + 1) * 512)) /dev/sdk >/home/user/backup.iso