Save this e.g. as “flasheos.sh”
Make it executable
Be sure to have all necessary pre-steps: Install /e/ on a Fairphone FP4 - “FP4” (beta)
Instead of installing each image separatly you can run the bash-script:
me@mylinux:/path/to/images/$ ./flasheos.sh
Thanks, looks ok.
Still I’m always wondering if it’s good (although it’s described as that in /e/ documentation) to flash both slots. Isn’t it better to just flash the inactive slot so in case anything goes wrong you still can switch back to the working old slot?
This is why I wrote this script while creating a draft of the “/e/OS easy installert”:
Linux flash script for flashing /e/OS to inactive FP4 slot
#!/bin/bash
# Copyright (C) 2020 - Author: Ingo; update and adoption to FP4, 2022 by Volker
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Exit status
# - 0 : /e/ installed
# - 1 : user data wipe failed
# - 2 : flashing of a partition failed
# - 4 : setting slot failed
# - 5 : flashing of a secure partition failed
# The script assumes fastboot is in the following folder. You may edit this folder in case it's installed elsewhere:
FASTBOOT_FOLDER_PATH="/usr/bin/"
FASTBOOT_PATH=${FASTBOOT_FOLDER_PATH}"fastboot"
echo "=== Flash inactive slot"
# if active slot b then flash slot a, else flash slot b
if [ "$($FASTBOOT_PATH getvar current-slot 2>&1 | grep -q "current-slot: b"; echo $?)" = 0 ]
then
echo "Flash inactive slot a"
echo "== start with one critical slot to check if critical is unlocked"
if ! "$FASTBOOT_PATH" flash xbl_config_a xbl_config.img ; then exit 5 ; fi
echo "flashed config"
sleep 1
echo "== flash uncritical slots"
if ! "$FASTBOOT_PATH" flash bluetooth_a bluetooth.img ; then exit 2 ; fi
echo "flashed bluetooth"
sleep 1
if ! "$FASTBOOT_PATH" flash dsp_a dsp.img ; then exit 2 ; fi
echo "flashed dsp"
sleep 1
if ! "$FASTBOOT_PATH" flash modem_a modem.img ; then exit 2 ; fi
echo "flashed modem"
sleep 1
if ! "$FASTBOOT_PATH" flash boot_a boot.img ; then exit 2 ; fi
echo "flashed boot"
sleep 1
if ! "$FASTBOOT_PATH" flash recovery_a recovery.img ; then exit 2 ; fi
echo "flashed recovery"
sleep 1
if ! "$FASTBOOT_PATH" flash dtbo_a dtbo.img ; then exit 2 ; fi
echo "flashed dtbo"
sleep 1
if ! "$FASTBOOT_PATH" flash vbmeta_system_a vbmeta_system.img ; then exit 2 ; fi
echo "flashed vbmeta_system"
sleep 1
if ! "$FASTBOOT_PATH" flash vbmeta_a vbmeta.img ; then exit 2 ; fi
echo "flashed vbmeta"
sleep 1
if ! "$FASTBOOT_PATH" flash featenabler_a featenabler.img ; then exit 2 ; fi
echo "flashed featenabler"
sleep 1
if ! "$FASTBOOT_PATH" flash core_nhlos_a core_nhlos.img ; then exit 2 ; fi
echo "flashed core_nhlos"
sleep 1
echo "=== Flash critical slots"
if ! "$FASTBOOT_PATH" flash devcfg_a devcfg.img ; then exit 5 ; fi
echo "flashed devcfg"
sleep 1
if ! "$FASTBOOT_PATH" flash xbl_a xbl.img ; then exit 5 ; fi
echo "flashed xbl"
sleep 1
if ! "$FASTBOOT_PATH" flash tz_a tz.img ; then exit 5 ; fi
echo "flashed tz"
sleep 1
if ! "$FASTBOOT_PATH" flash hyp_a hyp.img ; then exit 5 ; fi
echo "flashed hyp"
sleep 1
if ! "$FASTBOOT_PATH" flash keymaster_a keymaster.img ; then exit 5 ; fi
echo "flashed keymaster"
sleep 1
if ! "$FASTBOOT_PATH" flash abl_a abl.img ; then exit 5 ; fi
echo "flashed abl"
sleep 1
if ! "$FASTBOOT_PATH" flash aop_a aop.img ; then exit 5 ; fi
echo "flashed aop"
sleep 1
if ! "$FASTBOOT_PATH" flash imagefv_a imagefv.img ; then exit 5 ; fi
echo "flashed imagefv"
sleep 1
if ! "$FASTBOOT_PATH" flash multiimgoem_a multiimgoem.img ; then exit 5 ; fi
echo "flashed multiimgoem"
sleep 1
if ! "$FASTBOOT_PATH" flash qupfw_a qupfw.img ; then exit 5 ; fi
echo "flashed qupfw"
sleep 1
if ! "$FASTBOOT_PATH" flash uefisecapp_a uefisecapp.img ; then exit 5 ; fi
echo "flashed uefisecapp"
sleep 1
if ! "$FASTBOOT_PATH" --set-active=a ; then exit 4 ; fi
echo "boot from slot a selected"
sleep 1
else
echo "Flash inactive slot b"
echo "== start with one critical slot to check if critical is unlocked"
if ! "$FASTBOOT_PATH" flash xbl_config_b xbl_config.img ; then exit 5 ; fi
echo "flashed config"
sleep 1
echo "== flash uncritical slots"
if ! "$FASTBOOT_PATH" flash bluetooth_b bluetooth.img ; then exit 2 ; fi
echo "flashed bluetooth"
sleep 1
if ! "$FASTBOOT_PATH" flash dsp_b dsp.img ; then exit 2 ; fi
echo "flashed dsp"
sleep 1
if ! "$FASTBOOT_PATH" flash modem_b modem.img ; then exit 2 ; fi
echo "flashed modem"
sleep 1
if ! "$FASTBOOT_PATH" flash boot_b boot.img ; then exit 2 ; fi
echo "flashed boot"
sleep 1
if ! "$FASTBOOT_PATH" flash recovery_b recovery.img ; then exit 2 ; fi
echo "flashed recovery"
sleep 1
if ! "$FASTBOOT_PATH" flash dtbo_b dtbo.img ; then exit 2 ; fi
echo "flashed dtbo"
sleep 1
if ! "$FASTBOOT_PATH" flash vbmeta_system_b vbmeta_system.img ; then exit 2 ; fi
echo "flashed vbmeta_system"
sleep 1
if ! "$FASTBOOT_PATH" flash vbmeta_b vbmeta.img ; then exit 2 ; fi
echo "flashed vbmeta"
sleep 1
if ! "$FASTBOOT_PATH" flash featenabler_b featenabler.img ; then exit 2 ; fi
echo "flashed featenabler"
sleep 1
if ! "$FASTBOOT_PATH" flash core_nhlos_b core_nhlos.img ; then exit 2 ; fi
echo "flashed core_nhlos"
sleep 1
echo "=== Flash critical slots"
if ! "$FASTBOOT_PATH" flash devcfg_b devcfg.img ; then exit 5 ; fi
echo "flashed devcfg"
sleep 1
if ! "$FASTBOOT_PATH" flash xbl_b xbl.img ; then exit 5 ; fi
echo "flashed xbl"
sleep 1
if ! "$FASTBOOT_PATH" flash tz_b tz.img ; then exit 5 ; fi
echo "flashed tz"
sleep 1
if ! "$FASTBOOT_PATH" flash hyp_b hyp.img ; then exit 5 ; fi
echo "flashed hyp"
sleep 1
if ! "$FASTBOOT_PATH" flash keymaster_b keymaster.img ; then exit 5 ; fi
echo "flashed keymaster"
sleep 1
if ! "$FASTBOOT_PATH" flash abl_b abl.img ; then exit 5 ; fi
echo "flashed abl"
sleep 1
if ! "$FASTBOOT_PATH" flash aop_b aop.img ; then exit 5 ; fi
echo "flashed aop"
sleep 1
if ! "$FASTBOOT_PATH" flash imagefv_b imagefv.img ; then exit 5 ; fi
echo "flashed imagefv"
sleep 1
if ! "$FASTBOOT_PATH" flash multiimgoem_b multiimgoem.img ; then exit 5 ; fi
echo "flashed multiimgoem"
sleep 1
if ! "$FASTBOOT_PATH" flash qupfw_b qupfw.img ; then exit 5 ; fi
echo "flashed qupfw"
sleep 1
if ! "$FASTBOOT_PATH" flash uefisecapp_b uefisecapp.img ; then exit 5 ; fi
echo "flashed uefisecapp"
sleep 1
if ! "$FASTBOOT_PATH" --set-active=b ; then exit 4 ; fi
echo "boot from slot b selected"
sleep 1
fi
echo "=== Flash common slot"
if ! "$FASTBOOT_PATH" flash super super.img ; then exit 2 ; fi
echo "flashed super"
sleep 1
echo "=== Wipe user data and meta data in 5 seconds..."
sleep 5
if ! "$FASTBOOT_PATH" erase userdata ; then exit 1 ; fi
sleep 1
if ! "$FASTBOOT_PATH" erase metadata ; then exit 1 ; fi
echo "user and meta data wiped"
sleep 5
It will work perfectly fine on most systems, since you aren’t using any bashisms and your default interpreter (likely bash for debian) will know what to do with it without the shebang.
It’s just nice to be explicit in scripts, reduces the potential for surprising behaviour
That will probably mess with OTA updates. The A / B updater checks the hash for the unused slot it’s trying to install to and if that doesn’t match the expected one, the update will fail.
That’s an interesting point. Maybe you’re right and this would then be a deal breaker for this method… On the other side I’d flashed one slot and device was running from this slot. Still OTA worked later on… But I anyway havel to test it out more thoroughly…
Thats sure better, I only copy-pasted this from the website so that I don’t have to copy each line separatly. I also would think it is better to flash both slots
Interesting, maybe the /e/ updater is less strict
This is definitely the case for vanilla FPOS, there has been a discussion before about this: Can't install Dec 2021 update
They should probably be checking the hashes as described in Step 5 from Life of an A/B update in the Android documentation…
In any case as I understand it (and I’m by no means an expert here), there is no such thing as two usable slots on a phone with Android Verified Boot. The second slot is only used during OTA updates, but once the unused slot (with the update) has been successfully booted, Rollback Protection should make it impossible to boot from the old one.
That’s the point I’m thinking about…: in case something goes wrong (while flashing) you won’t be able to successfully boot the device and “rollback protection” should not yet have made it impossible - so the idea is to just select the other slot and you’re back to a working system… (well, actually still to be confirmed… )
I’m not sure I’d try to recover from a state with content from possibly two different sources in slot A and B, nuke and pave might be easier
If the problem arises during or after flashing the super partition, that system is probably unbootable anyway, since (as you noted in your script) that one isn’t slot specific…
But your experience might prove me wrong, I’m only trying to decipher the documentation myself