Little Bash-Script for Installing /e/ OS on FP4

Put this in a textfile in the same folder as you put the *.img files for /e/ OS:

#!/bin/bash
# bashscript for flashing e/OS on Fairphone
# all files needed to be in the directory where you run this script
#


fastboot flash bluetooth_a bluetooth.img
fastboot flash bluetooth_b bluetooth.img
fastboot flash devcfg_a devcfg.img
fastboot flash devcfg_b devcfg.img
fastboot flash dsp_a dsp.img
fastboot flash dsp_b dsp.img
fastboot flash modem_a modem.img
fastboot flash modem_b modem.img
fastboot flash xbl_a xbl.img
fastboot flash xbl_b xbl.img
fastboot flash tz_a tz.img
fastboot flash tz_b tz.img
fastboot flash hyp_a hyp.img
fastboot flash hyp_b hyp.img
fastboot flash keymaster_a keymaster.img
fastboot flash keymaster_b keymaster.img

fastboot flash abl_a abl.img
fastboot flash abl_b abl.img
fastboot flash boot_a boot.img
fastboot flash boot_b boot.img
fastboot flash recovery_a recovery.img
fastboot flash recovery_b recovery.img
fastboot flash dtbo_a dtbo.img
fastboot flash dtbo_b dtbo.img
fastboot flash vbmeta_system_a vbmeta_system.img
fastboot flash vbmeta_system_b vbmeta_system.img
fastboot flash vbmeta_a vbmeta.img
fastboot flash vbmeta_b vbmeta.img
fastboot flash super super.img

fastboot flash aop_a aop.img
fastboot flash aop_b aop.img
fastboot flash featenabler_a featenabler.img
fastboot flash featenabler_b featenabler.img
fastboot flash imagefv_a imagefv.img
fastboot flash imagefv_b imagefv.img
fastboot flash multiimgoem_a multiimgoem.img
fastboot flash multiimgoem_b multiimgoem.img
fastboot flash qupfw_a qupfw.img
fastboot flash qupfw_b qupfw.img
fastboot flash uefisecapp_a uefisecapp.img
fastboot flash uefisecapp_b uefisecapp.img
fastboot flash xbl_config_a xbl_config.img
fastboot flash xbl_config_b xbl_config.img
fastboot flash core_nhlos_a core_nhlos.img
fastboot flash core_nhlos_b core_nhlos.img

fastboot erase userdata
fastboot erase metadata

fastboot --set-active=a

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

Tested on debian/bookworm

3 Likes

You’re missing a “!” to get that shebang working :slightly_smiling_face:

#!/bin/bash

4 Likes

sry, still alpha :smiley: :upside_down_face:
interestingly it worked for me.??

1 Like

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

2 Likes

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 :slightly_smiling_face:

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 one comprehensive script :smiley::+1:

1 Like

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

thanks. corrected it.

2 Likes

Interesting, maybe the /e/ updater is less strict :thinking:
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.

1 Like

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… :wink: ) :thinking:

Interesting point :thinking:

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 :smirk:
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 :slightly_smiling_face:

1 Like

Yes, that’s why I flash this partition as last one… :sweat_smile:

And thanks for all the links! That’s very helpful!

3 Likes