16

I'm in the process of experimenting with backing up a Raspberry Pi (Raspbian) sd card. I'm using Win32DiskImager to read the image (from SD card reader) onto my HDD, successfully - but now the size issue. The image is just bigger than the original SD card and can only be written back to a bigger SD card, which, if you back that up has the same problem.

After creating an .img file, how can I remove all the unused space again? (is this because I used raspi-config to allocate all available space to the root?)

I tried to get an idea of what the partition(s) look like with Cygwin, but can't manage to get fdisk working (-bash: fdisk: command not found) - (after reading Image of a 16Gb card containing unpartitioned space at the end: Truncating possible?)

Renier Delport
  • 361
  • 1
  • 4
  • 12

3 Answers3

14

So the best way I have found is to use GParted (you can either use a Linux-based OS, or boot from a GParted Live USB). It is simple enough to find detailed instructions on how to do each of these steps in detail, but here is the general method I have found to work:

  1. Run GParted, find your SD card in the device list and shrink the main partition to as small as it will go.
  2. Take the value of the last sector of this partition and multiply this by the sector size (512 for me; I presume this is standard, although you can check this in GParted settings for your device): this will give you the total size in bytes to copy.
  3. Divide the total number of bytes by 4096 (round up if you need to - better to take a bit more space than not enough), and this will give you the 'count' to then enter into the following command at the terminal in a Linux environment (You can probably do this from the GParted Live USB operating system terminal or in Cygwin without sudo so long as you are running it as an administrator):

sudo dd if=/dev/mmcblk0 of=/path/to/your/file.img bs=4k count=<count>

Change the input device location if you need to. This should give you a final image file that is the smallest that it can be, omitting empty space.

Mike Roberts
  • 625
  • 1
  • 7
  • 13
  • I can verify that this works. I've just tried it a few minutes ago to go from an 8GB card to a 4GB card. This should work provided that your data is smaller than your destination card. – Aloha Jun 09 '16 at 17:05
  • Sort off forgot about this post since I moved on. Will try it out in the future. Seems like this is a common problem, so thanks for your input. – Renier Delport Jul 04 '16 at 16:48
  • This should be marked as the correct answer! Thanks! – rodripf Nov 19 '16 at 15:43
  • any way on Windows? – Flash Thunder Dec 19 '16 at 17:26
  • 1
    You can boot from a GParted Live USB. – Mike Roberts Dec 20 '16 at 11:36
  • If I choose a different blocksize e.g. 1M how would I calculate the numbers? I guess 512 * lastSector is the same. Sou would I use 4096/(4k*1M) = 4096 * 1/250? Where does the 4096 come from? – Andi Giga Sep 10 '19 at 15:49
  • 4096 is 4 * 1024, which is 4 * 1K. Using a larger block size would mean that you adjust the number that you divide by to get your count. count * bs needs to be larger than the total number of bytes. Just make sure that you know the number of bytes that are meant by k, M, etc. – Mike Roberts Sep 17 '19 at 11:46
11

The exists a nice tool called pishrink which reduces the size of a dd image as much as possible by shrinking the root partition. If you start up the restored image the first time the partition is expanded to it's maximum size again. If you run Windows just use your Linux on your Raspberry to shrink the image.

framp
  • 910
  • 7
  • 17
  • This is indeed a very good alternative, since the script provides options to automatically expand filesystem on first boot, to remove logs and secrets, to compress the image after shrinking. – gromain Oct 14 '20 at 09:56
  • @gromain Yes. In the mean time a lot additional useful functionality was added to pishrink by the community. – framp Oct 18 '20 at 12:06
  • pishrink really helped. Gparted not worked in my case because of errors. I used pishrink with options -vrd, folder with image was mounted through network from Windows machine. – Mykola Vasilaki Dec 14 '22 at 19:32
1

Newest version of Win32DiskImager has option Read Only Allocated Partitions. It writes only used space, not empty.

  1. Shrink partition on sd card with GParted.
  2. Create image with Win32DiskImager from bigger card.
  3. Write image with Win32DiskImager on smaller card using option mentionted higher.
  • This will only work if you shrink the root partition first using gparted or some such. Otherwise (as in the original case from the question), you have an image that takes up the entire card with no apparent empty space, so there is nothing for Win32DiskImager to skip. – goldilocks Jun 27 '21 at 14:49