Skip to content

Instantly share code, notes, and snippets.

@Keyaku
Forked from Linux4/factory_flash.sh
Last active January 23, 2025 22:22
Show Gist options
  • Save Keyaku/e9252e8a1f134a0fab635074a567920a to your computer and use it in GitHub Desktop.
Save Keyaku/e9252e8a1f134a0fab635074a567920a to your computer and use it in GitHub Desktop.
Flash Samsung factory image packages on Linux
#!/usr/bin/env bash
# Flash Samsung factory image packages on Linux
# Original Author: Linux4 (https://github.com/Linux4)
# Original Gist: https://gist.github.com/Linux4/243e4aab83867e2b3f4322c2a0eb5a3e
readonly SCRIPT="$(realpath "$0")"
readonly SCRIPT_NAME=$(basename "$SCRIPT")
readonly usage=(
"Usage: $SCRIPT_NAME [OPTIONS] <zip>"
"Flash Samsung factory image packages on Linux"
"Example: $SCRIPT_NAME SM-G960F_OXM_G960FXXU9FUE3.zip"
"Arguments:"
" [-h|--help] : Show this help message"
" [-f|--file] <zip> : Path to the factory image package"
" [-c|--clean] : Clean working directory"
" [-w|--wipe] : Wipe data partition"
)
### Functions
# Checks if file is a valid zip archive
function is_zip {
local -r zipfile="$(realpath "$1" 2>/dev/null)"
[[ -f "$zipfile" ]] && [[ "$zipfile" == *.zip ]] && file "$zipfile" | \grep -q "Zip archive data"
}
# Checks if given commands are installed
function command-has {
## function logic
local retval=0
local -a non_installed=()
while (( $# )); do
## If command is not installed, add to non_installed array
if ! command -v "$1" &>/dev/null; then
non_installed+=("$1")
fi
shift
done
## If any command is not installed, return 1
if (( ${#non_installed[@]} )); then
>&2 echo "Error: Please install the following packages:"
>&2 printf "\t%s\n" "${non_installed[*]}"
retval=1
fi
return $retval
}
# Get partition name from PIT file
function get_partition {
local -r pit="$1"
local -r part="$2"
./firmware-update/tools/pithelper/get-pit-partition "$pit" "$part"
}
### Main
# Check for required commands
typeset -a REQUIREMENTS=(git g++ heimdall lz4 make unzip)
command-has "${REQUIREMENTS[@]}" || exit 1
# Argument parsing
VALID_ARGS=$(getopt -o chwf: --long clean,help,wipe,file: -- "$@")
eval set -- ${VALID_ARGS}
(( ! $# )) && echo "${usage[0]}" && exit 1
while (( $# )); do
case "$1" in
-h|--help)
b_help=y
break
;;
-f|--file)
shift
if is_zip "$1"; then
ZIP="$(realpath "$1")"
else
>&2 echo "Invalid zip file: '$1'"
fi
;;
-w|--wipe)
b_wipe=y
;;
-c|--clean)
# Clean working directory
b_clean=y
;;
# Positional arguments
--) : # shift; break
;;
*)
if is_zip "$1"; then
ZIP="$(realpath "$1")"
else
>&2 echo "Invalid argument: '$1'"
fi
;;
esac
shift
done
# Argument validation
if [[ -z "$ZIP" ]] || [[ "$b_help" =~ y(es)? ]]; then
[[ -z "$ZIP" ]] && >&2 echo "Error: No zip file specified"
>&2 printf "%s\n" "${usage[@]}"
[[ "$b_help" =~ y(es)? ]]; exit $?
fi
# Set working directory
workdir="${ZIP%.*}"
[[ "$b_clean" =~ y(es)? ]] && rm -rf "$workdir"
[[ ! -d "$workdir" ]] && mkdir "$workdir"
cd "$workdir"
# Unpack the zip file and respective tar files
[[ "$b_wipe" =~ y(es)? ]] && CSC="CSC" || CSC="HOME_CSC"
for fw_part in BL AP CP "$CSC"; do
echo "Unpacking $fw_part"
unzip "$ZIP" "${fw_part}*"
tar xf "${fw_part}"*.md5
rm "${fw_part}"*.md5
done
# Extract PIT which is only in regular CSC package, not HOME_CSC
[[ "$b_wipe" =~ y(es)? ]] || unzip -p "$ZIP" "CSC*" | tar xf - --wildcards "*.pit"
for LZ4 in *.lz4; do
lz4 -d "$LZ4"
rm -f "$LZ4"
done
PIT="$(ls *.pit)"
echo "Using PIT $PIT"
[[ ! -d firmware-update ]] && git clone https://github.com/Linux4/firmware-update
make -C firmware-update/tools/pithelper
typeset -a HEIMDALL_CMD
for fw_part in *; do
[[ ! -f "$fw_part" ]] && continue
[[ "$fw_part" == "$PIT" ]] && continue
fw_partname="$(basename $fw_part)"
[[ "$b_wipe" =~ n(o)? ]] && [[ "$fw_partname" == "userdata.img" ]] && continue
PARTITION="$(get_partition $PIT $fw_partname)"
[[ -z "$PARTITION" ]] && echo "Error: $fw_part not assigned to any partition" && exit 1
HEIMDALL_CMD+=(--${PARTITION} ${fw_part})
done
heimdall flash --verbose ${HEIMDALL_CMD[@]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment