## flash_FP6_factory.sh
#!/usr/bin/env bash
# Target device info
PRODUCT="Fairphone 6"
PRODUCT_ID="FP6"
# Target Flashing Images info
FLASH_AB_FW_IMGS="bluetooth devcfg dsp modem xbl tz hyp keymaster abl aop featenabler imagefv multiimgoem qupfw uefisecapp xbl_config aop_config cpucp_dtb uefi vm-bootsys xbl_ramdump cpucp shrm studybk"
FLASH_AB_IMGS="boot dtbo vbmeta_system vbmeta init_boot pvmfw recovery vendor_boot"
FLASH_A_IMGS="super"
ERASE_IMGS="misc userdata metadata"
# Target flash process behavior
CLEAN_FLASH=true
VIRTUAL_AB=true
source factory.common
# Common flashing function
flash_factory
## factory.common
#!/usr/bin/env bash
set -e
# Paths/files
ROOT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
IMAGES_DIR="${ROOT_DIR}"
# Abort the script (and wait for a key to be pressed).
abort_now() {
echo ""
read -rp "ERROR: Aborting now (press Enter to terminate)." a
exit 1
}
# Check if the device is properly unlocked
check_unlock_status() {
local PHONE_IS_READY=true
if ("${FASTBOOT_BIN}" getvar is-userspace 2>&1 | grep -q yes); then
echo "Info: Your phone is in fastbootD mode."
if ("${FASTBOOT_BIN}" getvar unlocked 2>&1 | grep -q no); then
echo "Error: Your device's bootloader is still locked."
echo "Please follow the instructions to unlock the bootloader!"
PHONE_IS_READY=false
fi
else
echo "Info: Your phone is in regular bootloader mode."
if ("${FASTBOOT_BIN}" getvar unlocked 2>&1 | grep -q no); then
echo "Error: Your device's bootloader is still locked."
echo "Please follow the instructions to unlock the bootloader!"
PHONE_IS_READY=false
fi
if ("${FASTBOOT_BIN}" oem device-info 2>&1 | grep -q "critical unlocked: false"); then
echo "Error: Critical partitions are still locked."
echo "Did you execute 'fastboot flashing unlock_critical'?"
PHONE_IS_READY=false
fi
fi
if [ "$PHONE_IS_READY" = "false" ]; then
echo "Error: Your phone is not ready for flashing yet (see above), aborting..."
exit 1
fi
}
# Erase a list of partitions. Abort on failure.
# Arguments:
erase_images_or_abort() {
if [ -n "${2}" ]
then
for PARTITION in $2;
do
local retval=0
"${FASTBOOT_BIN}" -s "${1}" erase "${PARTITION}" || retval=$?
if [ "${retval}" -ne 0 ]
then
echo ""
echo "ERROR: Could not erase the ${PARTITION} partition on device ${1}."
echo ""
echo "ERROR: Please unplug the phone, take the battery out, boot the device into"
echo "ERROR: fastboot mode, and start this script again."
echo "ERROR: (To get to fastboot mode, press Volume-Down and plug in the USB-C)"
echo "ERROR: (cable until the fastboot menu appears.)"
abort_now
fi
done
fi
}
# Check for connected phone
find_device() {
echo "INFO: Looking for connected device(s)..."
DEVICE_FOUND="false"
while [ ${DEVICE_FOUND} = "false" ]
do
serial_numbers=
for sn in $("${FASTBOOT_BIN}" devices | grep fastboot | grep -oE '^[[:alnum:]]+')
do
# Checking the product ID
PRODUCT_STRING=$("${FASTBOOT_BIN}" -s "${sn}" getvar product 2>&1)
# Add serial, if product matches
if [[ ${PRODUCT_STRING} == *"${PRODUCT_ID}"* ]] || [[ ${PRODUCT_STRING} == *"${PRODUCT_ID_OLD}"* ]]
then
serial_numbers="${serial_numbers} $sn"
fi
done
case $(echo "${serial_numbers}" | wc -w | grep -oE '[0-9]+') in
0)
echo ""
echo "WARNING: No ${PRODUCT} found in fastboot mode."
echo "WARNING: Make sure that a ${PRODUCT} is connected."
;;
1)
echo "INFO: One ${PRODUCT} in fastboot mode found (serial number: ${sn})."
DEVICE_FOUND="true"
break
;;
*)
echo ""
echo "WARNING: Several ${PRODUCT}'s in fastboot mode connected."
echo "WARNING: Please connect only one ${PRODUCT}."
;;
esac
echo ""
while true
do
read -rp "Do you want to look for a ${PRODUCT} again? [(Y)es/(n)o]: " a
if [ -z "${a}" ] || [ "${a}" = 'y' ] || [ "${a}" = 'Y' ]
then
break
elif [ "${a}" = 'n' ] || [ "${a}" = 'N' ]
then
exit 0
fi
done
done
}
# Switch to fastbootd
switch_to_fastbootd() {
echo "INFO: Switching device to fastbootd mode..."
"${FASTBOOT_BIN}" -s "${sn}" reboot fastboot || {
echo "ERROR: Unable to switch to fastbootd mode."
abort_now
}
sleep 5 # Wait for the device to reboot into fastbootd
echo "INFO: Device is now in fastbootd mode."
}
# Flash (or manipulate) relevant partitions
flash_device() {
flash_images_ab_or_abort "${sn}" "${FLASH_AB_FW_IMGS}"
flash_images_a_or_abort "${sn}" "${FLASH_A_FW_IMGS}"
if [ "${FW_BL_RESTART}" = "true" ]
then
echo "INFO: Firmware images flashed. The device will reboot to bootloader again to continue."
"${FASTBOOT_BIN}" -s "${sn}" reboot bootloader
fi
flash_images_ab_or_abort "${sn}" "${FLASH_AB_IMGS}"
flash_images_a_or_abort "${sn}" "${FLASH_A_IMGS}"
if [ "${CLEAN_FLASH}" = "true" ]
then
erase_images_or_abort "${sn}" "${ERASE_IMGS}"
format_images_or_abort "${sn}" "${FORMAT_IMGS}"
fi
if [ "${VIRTUAL_AB}" = "true" ]
then
"${FASTBOOT_BIN}" -s "${sn}" --set-active=a
fi
}
# Common flash function to be called from device flash script
flash_factory() {
# Begin with some OS checks and variable definition
os_checks
# Call function to look for device(s)
# If only one device is found $sn will store its serial number
find_device
if [ "${USE_FASTBOOTD}" = "true" ]; then
switch_to_fastbootd
fi
# Check if the device is properly unlocked
check_unlock_status
# Flash the device
flash_device
# Reboot device
reboot_device
}
# Flash an image to a partition. Abort on failure.
# Arguments:
flash_image_or_abort() {
local retval=0
"$FASTBOOT_BIN" -s "${1}" flash "${2}" "${3}" || retval=$?
if [ "${retval}" -ne 0 ]
then
echo ""
echo "ERROR: Could not flash the ${2} partition on device ${1}."
echo ""
echo "ERROR: Please unplug the phone, take the battery out, boot the device into"
echo "ERROR: fastboot mode, and start this script again."
echo "ERROR: (To get to fastboot mode, press Volume-Down and plug in the USB-C)"
echo "ERROR: (cable until the fastboot menu appears.)"
abort_now
fi
}
# Flash an image to both A and B slot of partition. Abort on failure.
# Arguments:
flash_image_ab_or_abort() {
flash_image_or_abort "${1}" "${2}_a" "${3}"
flash_image_or_abort "${1}" "${2}_b" "${3}"
}
# Flash a list of images to partitions. Abort on failure.
# Arguments:
flash_images_a_or_abort() {
if [ -n "${2}" ]
then
for BLOB in $2;
do
PARTITION="${BLOB%%:*}"
IMAGE=$(echo $BLOB | cut -s -d : -f 2)
if [[ "$PARTITION" = "userdata" && "${CLEAN_FLASH}" != "true" ]]
then
continue
fi
flash_image_or_abort "${1}" "${PARTITION}" "${IMAGES_DIR}/${IMAGE:-$PARTITION.img}"
done
fi
}
# Flash a list of images to A and B slot of partitions. Abort on failure.
# Arguments:
flash_images_ab_or_abort() {
if [ -n "${2}" ]
then
for BLOB in $2;
do
PARTITION="${BLOB%%:*}"
IMAGE=$(echo $BLOB | cut -s -d : -f 2)
flash_image_ab_or_abort "${1}" "${PARTITION}" "${IMAGES_DIR}/${IMAGE:-$PARTITION.img}"
done
fi
}
# Erase a list of partitions. Abort on failure.
# Arguments:
format_images_or_abort() {
if [ -n "${2}" ]
then
for PARTITION in $2;
do
local retval=0
"${FASTBOOT_BIN}" -s "${1}" format "${PARTITION}" || retval=$?
if [ "${retval}" -ne 0 ]
then
echo ""
echo "ERROR: Could not format the ${PARTITION} partition on device ${1}."
echo ""
echo "ERROR: Please unplug the phone, take the battery out, boot the device into"
echo "ERROR: fastboot mode, and start this script again."
echo "ERROR: (To get to fastboot mode, press Volume-Down and plug in the USB-C)"
echo "ERROR: (cable until the fastboot menu appears.)"
abort_now
fi
done
fi
}
# Operating system checks and variable definition
os_checks() {
case "$(uname -s 2> /dev/null)" in
Linux|GNU/Linux)
echo "INFO: You are using a Linux distribution."
FASTBOOT_BIN="${ROOT_DIR}/bin-linux-x86/fastboot"
;;
msys|MINGW*)
echo "INFO: You are using MinGW on Windows."
FASTBOOT_BIN="${ROOT_DIR}/bin-msys/fastboot.exe"
;;
Darwin)
echo "INFO: You are using MacOS."
FASTBOOT_BIN="${ROOT_DIR}/bin-darwin/fastboot"
;;
*)
echo "ERROR: Unsupported operating system (${OSTYPE})."
echo "ERROR: Only GNU/Linux, MacOS and MinGW on Windows are currently supported."
abort_now
;;
esac
}
# Control the reboot sequence
reboot_device() {
echo "-----------"
echo ""
echo "INFO: Done. The device will reboot now."
"${FASTBOOT_BIN}" -s "${sn}" reboot
echo ""
echo "INFO: You can unplug the USB cable now."
echo ""
}