truncate
is a good tool. You need to shrink the image, so it contains every partition defined in the partition table. In other words, if the end sector of the partition closest to the end is N
(note it doesn't have to be the partition with the highest number), you need N+1
sectors of the image (+1
because numbering starts at 0
).
Use gdisk -l image
to know the N
.
Most likely the card uses 512-byte sectors and the partition table is valid when interpreted in terms of 512-byte sectors (for comparison: see what happens when this assumption does not hold). So you need (N+1)*512
bytes (or more, having more is not fatal). truncate
accordingly.
Reading this number of bytes directly from the card in the first place would give you the same result. An easy way (although non-POSIX, see this) is head -c number-of-bytes-here /dev/sdx > image
.
Then you need 33 additional logical sectors for a secondary (backup) GPT. Use truncate
again and add 33*512
bytes to the file (truncate -s +16896 image
). We could have shrunk the image to the desired final size with the first truncate
(or read more with head
), but doing this in two steps causes these additional 33 sectors to contain zeros instead of garbage that might interfere in a moment.
The first truncating (or creating a partial image) discarded the original secondary GPT. Use gdisk image
and let it fix the problem. It will tell you that disk size is smaller than the main header indicates
and invalid backup GPT header, but valid main header; regenerating backup header from main header
. Thanks to the second truncate
there is room for the backup GPT. All you need is to "w
rite table to disk and exit"; the tool will rewrite GPT, including the backup one.
gunzip -c image.gz |dd of=/dev/sdx
(adapt to your card's device file) – Philippos May 27 '22 at 07:43