If you do regular deployments you can create an image. A reasonable approach is to:
- Shrink the last partition
- Zero fill the remaining free space
- Find the end of the last partition
- DD that to a file
- Use raspi-config to resize after deploying
Or you can use PiShrink to script all that.
wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh chmod +x pishrink.sh sudo mv pishrink.sh /usr/local/bin
# Capture and shrink the image sudo dd if=/dev/mmcblk0 of=anthias-raw.img bs=1M sudo pishrink.sh anthias-raw.img anthias.img # Copy to a new card sudo dd if=anthias.img of=/dev/mmcblk0 bs=1M
If you need to modify the image after creating it you can mount it via loop-back.
sudo losetup --find --partscan anthias.img sudo mount /dev/loop0p2 /mnt/ # After you've made changes sudo umount /mnt sudo losetup --detach-all
If you have access to a graphical desktop environment, use GParted. It will resize the filesystem and partitions for you quite easily.
# Mount the image via loopback and open it with GParted sudo losetup --find --partscan anthias-raw.img # Grab the right side of the last partition with your mouse and # drag it as far to the left as you can, apply and exit sudo gparted /dev/loop0
Now you need to find the last sector and truncate the file after that location. Since the
truncate utility operates on bytes, you convert sectors to bytes with multiplication.
# Find the End of the last partition. In the below example, it's Sector *9812664* $ sudo fdisk -lu /dev/loop0 Units: sectors of 1 * 512 = 512 bytes Device Boot Start End Sectors Size Id Type /dev/loop0p1 8192 532479 524288 256M c W95 FAT32 (LBA) /dev/loop0p2 532480 9812664 9280185 4.4G 83 Linux sudo losetup --detach-all sudo truncate --size=$[(9812664+1)*512] anthias-raw.img
Very Manual Steps
If you don’t have a GUI, you can do it with a combination of commands.
# Mount the image via loopback sudo losetup --find --partscan anthias-raw.img # Check and resize the file system sudo e2fsck -f /dev/loop0p2 sudo resize2fs -M /dev/loop0p2 ... The filesystem on /dev/loop0p2 is now 1149741 (4k) blocks long # Now you can find the end of the resized filesystem by: # Finding the number of sectors. # Bytes = Num of blocks * block size # Number of sectors = Bytes / sector size echo $[(1149741*4096)/512] # Finding the start sector (532480 in the example below) sudo fdisk -lu /dev/loop0 Device Boot Start End Sectors Size Id Type /dev/loop0p1 8192 532479 524288 256M c W95 FAT32 (LBA) /dev/loop0p2 532480 31116287 30583808 14.6G 83 Linux # Adding the number of sectors to the start sector. Add 1 because you want to end AFTER the end sector echo $[532480 + 9197928 + 1] # And resize the part to that end sector (ignore the warnings) sudo parted resizepart 2 9730409
Great! Now you can follow the remainder of the GParted steps to find the new last sector and truncate the file.
It’s handy to compress the image.
xz is pretty good for this
xz anthias-raw.img xzcat anthias-raw.img | sudo dd of=/dev/mmcblk0
In these procedures, we make a copy of the SD card before we do anything. Another strategy is to resize the SD card directly, and then use
dd and read in X number of sectors rather than read it all in and then truncate it. A bit faster, if a but less recoverable from in the event of a mistake.
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.