Skip to content

Instantly share code, notes, and snippets.

@modeco80
Created March 19, 2020 23:05
Show Gist options
  • Save modeco80/3ba5d3f432b14c238eb84d1307b06432 to your computer and use it in GitHub Desktop.
Save modeco80/3ba5d3f432b14c238eb84d1307b06432 to your computer and use it in GitHub Desktop.
Script for easily backing up emuMMC partitions
#!/bin/bash
# written by modeco80 and BlockBuilder57
# interactive interface for inputting emuMMC partition
# used if device argument is ommited from the command line
# or if the device argument is invalid
get_partition() {
local _result=$1
# display connected disks
sudo fdisk -l
read -rp "Input the partition containing the emuMMC you wish to back up: " part
if [ ! -b "$part" ]; then
clear
echo "'$part' does not exist or is not a partition."
get_partition $_result
fi
eval $_result="$part"
}
# Disable splitting.
# Activated by -d | --disable-split.
bool_disable_split="n"
# Keep rawnand.
# Activated by -k | --keep-rawnand
bool_keep_rawnand="n"
# Default size. Can be customized with --custom-size.
# To calculate block size, do ((byte_count / 1024) / 1024) / 4.
size="7455"
# Backup filename.
backup_filename="emummc-backup-$(date +"%Y-%m-%d").tar.bz2"
if [ "$1" == "" ]; then
# run without arguments; interactively ask the user for the partition
get_partition "part"
else
# janky option getter
while true; do
case "$1" in
-h|--help)
echo -e "Usage:"
echo -e " $0 [-d|--disable-split] [--custom-size [SIZE]] [-k|-keep-rawnand] [-h|--help] [PARTITION]\n"
echo -e "PARTITION is optional, the script will provide interactive way to input device if ommited.\n"
echo -e "Options:"
echo -e "\t-d | --disable-split - disable splitting 'rawnand.bin' (if SD card filesystem is not FAT32)"
echo -e "\t--custom-size [SIZE] - dump [SIZE] blocks instead of default 7455 blocks."
echo -e "\t\t\t\t\bTo calculate block count, do (([SIZE_IN_BYTES] / 1024) / 1024) / 4."
echo -e "\t-k | --keep-rawnand - Keep 'rawnand.bin' when splitting."
echo -e "\t-h | --help - show this message"
exit
;;
-d|--disable-split)
bool_disable_split="y"
;;
-k|--keep-rawnand)
bool_keep_rawnand="y"
;;
--custom-size)
shift
if [ "$1" == "" ]; then
echo "error: Value required for --custom-size"
exit 1
else
case $1 in
''|*[!0-9]*)
echo "error: Value provided is not a number."
exit 1
;;
*)
size=$1
;;
esac
fi
;;
*)
# assume partition argument was found
part=$1
break
;;
esac
shift
done
if [ "$part" == "" ]; then
# no partition argument
get_partition "part"
fi
if [ ! -b "$part" ]; then
# launch interactive partition getter
echo "'$part' does not exist or is not a partition."
get_partition "part"
fi
fi
mkdir emummc-backup
pushd emummc-backup
# grab raw partition
echo "Reading in full partition..."
sudo dd if=$part bs=512 status=progress of=part.bin
# extract out fat32 stuff
echo "Removing FAT32 header..."
dd if=part.bin bs=512 skip=32768 status=progress of=data.bin
# extract BOOT0 and BOOT1
echo "Separating BOOT0 and BOOT1.."
dd if=data.bin bs=4M count=1 status=progress of=BOOT0
dd if=data.bin bs=4M count=1 skip=1 status=progress of=BOOT1
# extract actual nand data
echo "Separating rawnand.bin..."
dd if=data.bin bs=4M skip=2 count=$size status=progress of=rawnand.bin
# split nand data into parts
if [ "$bool_disable_split" == "n" ]; then
echo "Splitting rawnand.bin into seperate files...."
split -b 2G -a 2 -d --verbose rawnand.bin rawnand.bin.
fi
# clean up the rest
echo "Cleaning up...."
sudo rm part.bin
rm data.bin
if [[ "$bool_disable_split" == "n" ]] && [[ "$bool_keep_rawnand" == "n" ]]; then
rm rawnand.bin
fi
popd
echo "Creating tar.bz2 archive of backup..."
BZIP2=-9 tar cjvf $backup_filename emummc-backup/*
rm -rvf backup/
echo "Backup created at '$PWD/$backup_filename'."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment