## 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 "" }