Skip to content

Instantly share code, notes, and snippets.

@btashton
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save btashton/e5d18aac672da0e1e3fa to your computer and use it in GitHub Desktop.
Save btashton/e5d18aac672da0e1e3fa to your computer and use it in GitHub Desktop.
Resize Partitions on SD card Image

I had imaged a full 8GB SD card, but I only wanted to distribute a smaller image. These are a few notes:

Image the SD card

dd if=/dev/sdb of=./backup.img

Now I wanted to use gparted to resize the partition, you can run sudo gparted ./backup.img and it will show the partitions, but it will think that the partitions are located at /dev/./backup.img1 and /dev/./backup.img2 which is not correct. The trick here is to use the loopback interface.

losetup /dev/loop0 backup.img this will make the backup.img file show up as a block device. You can then run gparted on /dev/loop0 and once again see the partition table. There still is an issue though, it will look for the partitions to be located at /dev/loop0p1 and /dev/loop0p2, these block devices do not exist. It turns out that losetup has a flag that I have not noticed anywhere before -P this causes the kernel to read the partition table of the device and create the additional block device. This lets us avoid having to manually look at the partition table and compute the offsets for additional loopback devices.

losetup -P /dev/loop0 backup.img

$ sudo ls /dev/loop0*
/dev/loop0  /dev/loop0p1  /dev/loop0p2

Great! this now looks like a real device. gparted will work fine to resize the partitions and filesystems. I trimmed a 7.9GB partition back to 3GB and then saved the changes. This did not change how large backup.img is, it is still 8GB, but all the important data is now in the first 3GB or so of the disk (p1 in the case was a 50MB boot partition).

Lets do a quick check on the filesystems to make sure they are still looking good (just showing p2 here, p1 looks similar just a fat partition)

$ sudo fsck /dev/loop0p2 
fsck from util-linux 2.24.2
e2fsck 1.42.8 (20-Jun-2013)
/dev/loop2p2: clean, 83917/193152 files, 618580/768000 blocks

Alright, now lets clear up the end of the disk that is not being used. I used fdisk to take a look at the partition table:

$ sudo fdisk /dev/loop2

Welcome to fdisk (util-linux 2.24.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/loop0: 7.4 GiB, 7948206080 bytes, 15523840 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: 0x000981cb

Device       Boot     Start       End  Blocks  Id System
/dev/loop0p1           8192    122879   57344   c W95 FAT32 (LBA)
/dev/loop0p2         122880   6266879 3072000  83 Linux

Command (m for help): q

A couple things to note here. The sector size is 512 bytes. The end block of the last partition is 6266879. To compute the blocks we add one to the block number (they are indexed from 0) and then multiply this by the sector size 512. Using the truncate command we can trim this extra data off the file.

sudo truncate --size=$(((6266879+1)*512)) backup.img

It is now 5GB smaller

ls -lh ./
-rw-r--r--. 1 root root 3.0G Apr  2 13:53 backup.img
-rw-r--r--. 1 root root 8.0G Apr  2 13:53 backup.org.img

I recommend running the filesystem checks again, the first time I did this I used 510 instead of 512 for the sector size (not enough coffee) and everything broke and had to start all over with a fresh 8GB image.

I also highly recommend bz2 compressing the image file, you will likely save a significant amount of space.

-rw-r--r--. 1 root root 3.0G Apr  2 13:53 backup.img
-rw-r--r--. 1 root root 929M Apr  2 14:03 backup.img.tar.bz2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment