How to trim disk images to partition size

I’ve recently been playing with my Raspberry Pi and Arch Linux when I encountered the following problem:

I’ve downloaded the Arch Linux image from the Raspberry Pi download page and used dd to copy it to a 8GB SD card.

$ dd if=ArchLinuxARM-2014.01-rpi.img bs=1M of=/dev/sdc & PID=$!

I used

$ kill -USR1 $PID

to check the progress of the image transfer. The image itself is only 2GB in size, so there were 6GB of unused space, but what the heck. If you want you can use parted or gparted to extend the partition to the size of the SD card. After successfully booting up Arch Linux on the Raspberry Pi I started to configure it to my needs and installed some packages. When I was done with my configurations I decided to make an image of the configured Arch Linux. I used dd again to make an image of the SD card, but since the SD card has a size of 8GB the image was also 8GB in size. I did not want to waste 6GB of space on my harddrive, so I started looking for a solution and found this article.

First you have to find out the partition layout of the image with fdisk.

$ fdisk -l myimage.img

The output should look something like this:

Disk myimage.img: 7969 MB, 7969177600 bytes, 15564800 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
Disk identifier: 0x417ee54b

      Device Boot      Start         End      Blocks   Id  System
myimage.img1            2048      186367       92160    c  W95 FAT32 (LBA)
myimage.img2          186368     3667967     1740800    5  Extended
myimage.img5          188416     3667967     1739776   83  Linux

The information you need is the unit size (512 bytes) and the largest end block number (3667967). Since block counting starts at 0, you need to add 1 to the number of blocks. Now you can use truncate to trim the image to the size of the actually used space.

$ truncate --size=$[(3667967+1)*512] myimage.img

The resulting image file now has a size of approximately 1.8GB.

$ fdisk -l myimage.img

Disk myimage.img: 1877 MB, 1877999616 bytes, 3667968 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
Disk identifier: 0x417ee54b

      Device Boot      Start         End      Blocks   Id  System
myimage.img1            2048      186367       92160    c  W95 FAT32 (LBA)
myimage.img2          186368     3667967     1740800    5  Extended
myimage.img5          188416     3667967     1739776   83  Linux

Update:
You can produce an image file that only contains the partitioned part of the SD card. First check the partition layout of the SD card with

$ fdisk -l /dev/sdc

and then use dd with the units size and largest end block number + 1 to copy all partitions from the SD card to an image file. With the data from the example above you would enter

$ dd if=/dev/sdc bs=512 count=3667968 of=myimage.img & PID=$!

About h0nk3ym0nk3y

h0nk3ym0nk3y is one of the three LinuxM0nk3ys from Linux M0nk3ys @ WordPress Linux M0nk3ys @ YouTube Linux M0nk3ys @ Twitter

Posted on February 7, 2014, in Command-Line, Troubleshooting and tagged , , , , , , , , , , , , , , , . Bookmark the permalink. 1 Comment.

  1. Thanks, this worked great! I had been searching for the best way to backup my A20 box SD card image. The card is 64 GB but only 4 GBs are partitioned. Your way to do the backup is optimal, 1) it really works and 2) finishes in reasonable time (and image file size).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: