Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

Script to resize / shrink win32 disk imager retropie images



  • I have seen users discussing the inability to clone SD cards due to a few bytes difference, as well as copying larger image to a smaller card using win32 disk imager. I ran into a similar issue, so I'm posting this script to shrink an win32 disk imager .img file. It was pieced together (mostly from sirlagz.net) and modified to work "out of the box" with the Retropie distribution.

    This is for Linux use only, so you're using Windows on your main computer, you may want to setup a shared folder and then mount it from your pi. Instructions for doing so can be found here or here.

    Usage: sudo ./script.sh file.img (it will overwrite the .img file, so make a backup of your backup)

    Note: after writing the resized / shrunk .img file to your SD card, on first boot you'll want to sudo raspi-config and choose option 1 to expand the file system.

    #!/usr/bin/env bash
    
    if [[ -z "$1" ]]; then
      echo -e "usage: sudo $0 <file.img>\n"
      exit
    fi
    
    if [[ $(whoami) != "root" ]]; then
      echo -e "error: this must be run as root: sudo $0 <file.img>"
      exit
    fi
    
    
    if [[ ! -e "$1" ]]; then
      echo -e "error: no such file\n"
      exit
    fi
    
    orig_img_size=$(stat --printf="%s" "$1")
    
    part_info=$(parted -m "$1" unit B print)
    echo -e "\n[+] partition info"
    echo "----------------------------------------------"
    echo -e "$part_info\n"
    
    part_num=$(echo "$part_info" | grep ext4 | cut -d':' -f1)
    part_start=$(echo "$part_info" | grep ext4 | cut -d':' -f2 | sed 's/B//g')
    part_size=$(echo "$part_info" | grep ext4 | cut -d':' -f4 | sed 's/B//g')
    
    echo -e "[+] setting up loopback\n"
    loopback=$(losetup -f --show -o "$part_start" "$1")
    
    echo "[+] checking loopback file system"
    echo "----------------------------------------------"
    e2fsck -f "$loopback"
    
    echo -e "\n[+] determining minimum partition size"
    min_size=$(resize2fs -P "$loopback" | cut -d':' -f2)
    
    # next line is optional: comment out to remove 1% overhead to fs size
    min_size=$(($min_size + $min_size / 100))
    
    if [[ $part_size -lt $(($min_size * 4096 + 1048576)) ]]; then
      echo -e "\n[!] halt: image already as small as possible.\n"
      losetup -d "$loopback"
      exit
    fi
    
    echo -e "\n[+] resizing loopback fs (may take a while)"
    echo "----------------------------------------------"
    resize2fs -p "$loopback" "$min_size"
    sleep 1
    
    echo -e "[+] detaching loopback\n"
    losetup -d "$loopback"
    
    part_new_size=$(($min_size * 4096))
    part_new_end=$(($part_start + $part_new_size))
    
    echo -e "[+] adjusting partitions\n"
    parted "$1" rm "$part_num"
    parted "$1" unit B mkpart primary $part_start $part_new_end
    
    free_space_start=$(parted -m "$1" unit B print free | tail -1 | cut -d':' -f2 | sed 's/B//g')
    
    echo -e "[+] truncating image\n"
    truncate -s $free_space_start "$1"
    
    new_img_size=$(stat --printf="%s" "$1")
    bytes_saved=$(($orig_img_size - $new_img_size))
    echo -e "DONE: reduced "$1" by $(($bytes_saved/1024))KiB ($((bytes_saved/1024/1024))MB)\n"
    

    Alternatively, you can grab it from pastebin:

    curl -o shrink.sh http://pastebin.com/raw/TVih90By
    chmod a+x shrink.sh
    


  • Thanks a lot @synack :)
    I've think to do it from a long time ago with my image, i will try your script ;)



  • @synack This is exactly what I've been needing. I probably have a dozen or so Raspberry Pi modules (of all versions) scattered around the house (about half in active use for one thing or another). When a new release comes out the first thing I do is download it and configure it with the common tools I need for all projects and then save it off so that I don't have to go through the configuration process each time. This means that I run into exactly the problem you describe. My solution in the past has been to (if I remember) do the configuration on an 8GB MicroSD card and then deploy using a 16GB card. Your solution is optimal and will save me a lot of space on my disk. I just tried an example and it reduced a 16GB image file down to less than the size of the original unconfigured file (one of the things I do is delete a lot of large applications that I don't use so that updates go quicker). Thank you very much for taking the time to develop this script and share it with the community.

    Regards,
    Dave



  • @DaveHarper You might want to use this instead. https://github.com/Drewsif/PiShrink



  • @MajorDangerNine Thanks - I'll check it out.



Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.

Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.