/e/OS - Android 14 2.7 GSI bring-up

This is written assuming you are using the newest Linux Mint Cinnamon.
(which doesn’t have nsjail errors unlike ubuntu.)

Open your terminal in Mint and issue:

sudo apt-get update && sudo apt-get upgrade

after the upgrade completes, now we need to get the dependencies needed to build from source:

sudo apt-get install git ccache automake lzop gperf build-essential zip curl zlib1g-dev zlib1g-dev:i386 g+±multilib python3 libxml2-utils bzip2 libbz2-dev libbz2-1.0 libghc-bzlib-dev squashfs-tools pngcrush schedtool dpkg-dev liblz4-tool make optipng maven

Next we need to pick up Openjdk 11:

sudo apt-get install openjdk-11-jdk

Now to install repo and git.

sudo apt-get install repo

sudo apt-get install git

sudo apt-get install git-lfs

With this, finally create a folder for eOS, call it Lineage21.

Open terminal inside of it, issue:

repo init -u e / os / android · GitLab -b v1-u --git-lfs

then issue:

git clone GitHub - AndyCGYan/lineage_build_unified: Unified script for building GSI and device-specific LineageOS lineage_build_unified -b lineage-21-light

Replace the buildbot_unified.sh file’s contents with the following:

#!/bin/bash
echo “”
echo “/e/OS Unified Buildbot”
echo “Executing in 2 seconds - CTRL-C to exit”
echo “”
sleep 2

if [ $# -lt 2 ]
then
echo “Not enough arguments - exiting”
echo “”
exit 1
fi

MODE=${1}
if [ ${MODE} != “device” ] && [ ${MODE} != “treble” ]
then
echo “Invalid mode - exiting”
echo “”
exit 1
fi

NOSYNC=false
PERSONAL=false
SIGNABLE=true
for var in “${@:2}”
do
if [ ${var} == “nosync” ]
then
NOSYNC=true
fi
if [ ${var} == “personal” ]
then
PERSONAL=true
SIGNABLE=false
fi
done
if [ ! -d “$HOME/.android-certs” ]; then
read -n1 -r -p $“$HOME/.android-certs not found - CTRL-C to exit, or any other key to continue”
echo “”
SIGNABLE=false
fi

Abort early on error

set -eE
trap ‘(
echo;
echo !!! An error happened during script execution;
echo !!! Please check console output for bad sync,;
echo !!! failed patch application, etc.;
echo
)’ ERR

START=date +%s
BUILD_DATE=“$(date -u +%Y%m%d)”

prep_build() {
echo “Preparing local manifests”
mkdir -p .repo/local_manifests
cp ./lineage_build_unified/local_manifests_${MODE}/*.xml .repo/local_manifests
echo “”

echo "Syncing repos"
repo sync -c --force-sync --no-clone-bundle --no-tags -j$(nproc --all)
echo ""

echo "Pull /e/OS prebuilts"
repo forall -c 'git lfs pull'
echo ""

echo "Setting up build environment"
source build/envsetup.sh &> /dev/null
source vendor/lineage/vars/aosp_target_release
mkdir -p ~/build-output
echo ""

}

prep_device() {
:
}

prep_treble() {
:
}

finalize_device() {
:
}

finalize_treble() {
:
}

build_device() {
brunch ${1}
mv $OUT/lineage-*.zip ~/build-output/lineage-21.0-$BUILD_DATE-UNOFFICIAL-${1}$($PERSONAL && echo “-personal” || echo “”).zip
}

build_treble() {
case “${1}” in
(“64VN”) TARGET=gsi_arm64_vN;;
(“64VS”) TARGET=gsi_arm64_vS;;
(“64GN”) TARGET=gsi_arm64_gN;;
(*) echo “Invalid target - exiting”; exit 1;;
esac
lunch lineage_${TARGET}-${aosp_target_release}-userdebug
make installclean
WITH_ADB_INSECURE=true make -j$(lscpu -b -p=Core,Socket | grep -v ‘^#’ | sort -u | wc -l) systemimage
SIGNED=false
if [ ${SIGNABLE} = true ] && [[ ${TARGET} == *_g? ]]
then
make -j$(lscpu -b -p=Core,Socket | grep -v ‘^#’ | sort -u | wc -l) target-files-package otatools
bash ./lineage_build_unified/sign_target_files.sh $OUT/signed-target_files.zip
unzip -joq $OUT/signed-target_files.zip IMAGES/system.img -d $OUT
SIGNED=true
echo “”
fi
mv $OUT/system.img ~/build-output/lineage-21.0-$BUILD_DATE-UNOFFICIAL-${TARGET}$(${PERSONAL} && echo “-personal” || echo “”)$(${SIGNED} && echo “-signed” || echo “”).img
}

if ${NOSYNC}
then
echo “ATTENTION: syncing/patching skipped!”
echo “”
echo “Setting up build environment”
source build/envsetup.sh &> /dev/null
source vendor/lineage/vars/aosp_target_release
echo “”
else
prep_build
echo “Applying patches”
prep_${MODE}
apply_patches patches_platform
apply_patches patches_${MODE}
if ${PERSONAL}
then
apply_patches patches_platform_personal
apply_patches patches_${MODE}personal
fi
finalize
${MODE}
echo “”
fi

for var in “${@:2}”
do
if [ ${var} == “nosync” ] || [ ${var} == “personal” ]
then
continue
fi
echo "Starting $(${PERSONAL} && echo “personal " || echo “”)build for ${MODE} ${var}”
build_${MODE} ${var}
done
ls ~/build-output | grep ‘lineage’ || true

END=date +%s
ELAPSEDM=$(($(($END-$START))/60))
ELAPSEDS=$(($(($END-$START))-$ELAPSEDM*60))
echo “Buildbot completed in $ELAPSEDM minutes and $ELAPSEDS seconds”
echo “”

Finally, go to your terminal in the Lineage21 folder and issue the following command:

bash lineage_build_unified/buildbot_unified.sh treble 64VN 64VS 64GN

It will begin repo syncing and adding GSI manifests, repo sync may fail on the first attempt so run it until it fails patching.

Once repo is sync’d, and patching fails we’re done using the build bot.

Now to begin building, in terminal issue the following:

. build/envsetup.sh &> /dev/null

. vendor/lineage/vars/aosp_target_release

**breakfast gsi_arm64_vS **

brunch gsi_arm64_vS

After a really long time (if you are building using inferior HW) it will produce a system.img

This system.img may be flashed as a GSI.

Resolved Issues:

  • Duplicate sensor IDs

Current Issue:

01-03 15:46:30.666  3427  3427 I PermissionManager: Permission ownership changed. Updating all permissions.
01-03 15:46:30.668  3427  3427 W PermissionManager: Privileged permission android.permission.INSTALL_PACKAGES for package me.phh.treble.app (/system/priv-app/TrebleApp) not in privapp-permissions allowlist
01-03 15:46:30.668  3427  3427 W PermissionManager: Privileged permission android.permission.INTERACT_ACROSS_USERS for package me.phh.treble.app (/system/priv-app/TrebleApp) not in privapp-permissions allowlist
01-03 15:46:30.676  3427  3427 E System  : ******************************************
01-03 15:46:30.676  3427  3427 E System  : ************ Failure starting system services
01-03 15:46:30.676  3427  3427 E System  : java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions allowlist: {me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INSTALL_PACKAGES, me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INTERACT_ACROSS_USERS}
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.server.pm.permission.PermissionManagerServiceImpl.onSystemReady(PermissionManagerServiceImpl.java:4401)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.server.pm.permission.PermissionManagerService$PermissionManagerServiceInternalImpl.onSystemReady(PermissionManagerService.java:817)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:4302)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2964)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.server.SystemServer.run(SystemServer.java:980)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.server.SystemServer.main(SystemServer.java:701)
01-03 15:46:30.676  3427  3427 E System  : 	at java.lang.reflect.Method.invoke(Native Method)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
01-03 15:46:30.676  3427  3427 E System  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:856)
01-03 15:46:30.676  3427  3427 V SystemServerTiming: MakePackageManagerServiceReady took to complete: 12ms
01-03 15:46:30.676  3427  3427 E Zygote  : System zygote died with fatal exception
01-03 15:46:30.676  3427  3427 E Zygote  : java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions allowlist: {me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INSTALL_PACKAGES, me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INTERACT_ACROSS_USERS}
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.server.pm.permission.PermissionManagerServiceImpl.onSystemReady(PermissionManagerServiceImpl.java:4401)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.server.pm.permission.PermissionManagerService$PermissionManagerServiceInternalImpl.onSystemReady(PermissionManagerService.java:817)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:4302)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2964)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.server.SystemServer.run(SystemServer.java:980)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.server.SystemServer.main(SystemServer.java:701)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at java.lang.reflect.Method.invoke(Native Method)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
01-03 15:46:30.676  3427  3427 E Zygote  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:856)
01-03 15:46:30.676  3427  3427 D AndroidRuntime: Shutting down VM
01-03 15:46:30.676  3427  3427 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main
01-03 15:46:30.676  3427  3427 E AndroidRuntime: java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions allowlist: {me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INSTALL_PACKAGES, me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INTERACT_ACROSS_USERS}
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.server.pm.permission.PermissionManagerServiceImpl.onSystemReady(PermissionManagerServiceImpl.java:4401)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.server.pm.permission.PermissionManagerService$PermissionManagerServiceInternalImpl.onSystemReady(PermissionManagerService.java:817)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:4302)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2964)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.server.SystemServer.run(SystemServer.java:980)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.server.SystemServer.main(SystemServer.java:701)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
01-03 15:46:30.676  3427  3427 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:856)

Error relating to the privapp-permissions allowlist for the app me.phh.treble.app.

This is caused by the GSI system image lacking proper permissions configuration.

I will update this topic as I make progress, as issues arise in source I will do my best to patch them to bring up a GSI codebase for /e/OS.

1 Like

Hi, will your /e/OS-U GSI be able to receive OTA updates if the technical requirements of a device of this Project Treble (arm64 / A/B-Device / Seamless Upgrades / Dynamic Partitions) are met?

Note

These patches are HIGHLY experimental, I am for the purpose of being completely transparent documenting everything that I’ve changed in Lineage source to resolve issues booting this GSI.

Patches:

Add solution for duplicate IDs (builds but untested)

/e/OS-T GSI and /eOS-U GSI - that would be a pleasure :heart_eyes:

Right now, my build is at 25% completed with an ETA of 10 hours.

I have been cheating it and building the modules separately to confirm that my changes have good source integrity, I have replaced:

            // Use the BiometricRegistrationManager to handle the registration
            if (!mBiometricRegistrationManager.registerAuthenticator(id, modality, strength, authenticator)) {
                return;

with

            // Check for existing sensor with the same ID
            BiometricSensor existingSensor = null;
            for (BiometricSensor sensor : mSensors) {
                if (sensor.id == id) {
                    existingSensor = sensor;
                    break;
                }
            }
            // If the sensor already exists, log and replace it
            if (existingSensor != null) {
                Slog.w(TAG, "Replacing existing authenticator with ID: " + id);
                mSensors.remove(existingSensor);

With this change, when /e/OS GSI tries to register a sensor twice from it’s own self and from the vendor, the duplicate sensor ID should be updated, rather than throwing a ROM crashing error.

This is a very hacky solution, I will have to properly implement a registration manager in the future but that is honestly too much work to do a boot test, redundancies can be addressed after this boots.

For people watching this thread who want to help, build the GSI according to the listed instructions and provide the logcat here, I will address the errors.

In any event, I cannot get back to my source building hardware for another week or two at the earliest, I’m presently using a laptop with 8GB RAM to build this.

The changes I’m making are not part of the repo synced codebase, the patched files can be applied by either editing the manifest or by just outright replacing the file in source.

Sorry was a typo… I still can’t build GSIs

1 Like

As far as I know you need at least 16GB to build…

In Linux mint you have two options:

1: Create a SWAP partition of 64GB

This is fairly straightforward but is deprecated with the advent of the swap file, although it is somewhat faster swap (I don’t use this though)

2: Modify your Swap file to be 64GB

This is done by issuing the following to terminal:

sudo swapoff -a

sudo fallocate -l 56G /swapfile
(This gives the swap file a size of 56G + the 8 I have for a total of 64.)

sudo chmod 600 /swapfile

sudo mkswap /swapfile

sudo swapon /swapfile

and verify it is working by:

free -m

which returns:

image

Next up is giving your JVM heap a greater size which is accomplished by issuing

export _JAVA_OPTIONS=“-Xmx32g”

This gives it 32G which is overkill, but I’m building using a 1tb SSD so it is fine.

I always stop the build at intervals of 20% to allow my SSD to rest, then resume, but here you can see it is building without issue, it just takes FOREVER because the SSD is only 10% as fast as RAM.

Building a GSI is basically the same as building a stock ROM, use GSI device files and props and brunch it; then boot it on a test device using adb logcat and resolve errors in source

Alright, I’ve resolved the duplicate sensor ID issue!

Now this issue is thrown:

01-03 15:46:30.668  3427  3427 W PermissionManager: Privileged permission android.permission.INSTALL_PACKAGES for package me.phh.treble.app (/system/priv-app/TrebleApp) not in privapp-permissions allowlist
01-03 15:46:30.668  3427  3427 W PermissionManager: Privileged permission android.permission.INTERACT_ACROSS_USERS for package me.phh.treble.app (/system/priv-app/TrebleApp) not in privapp-permissions allowlist
01-03 15:46:30.676  3427  3427 E System  : ******************************************
01-03 15:46:30.676  3427  3427 E System  : ************ Failure starting system services
01-03 15:46:30.676  3427  3427 E System  : java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions allowlist: {me.phh.treble.app (/system/priv-app/TrebleApp): android.permission.INSTALL_PACKAGES,

To resolve it, create a privapp-permissions-platform.xml in the path:

/frameworks/base/core/res/res/xml/

Add the following to it:

<privapp-permissions package="me.phh.treble.app">
    <permission name="android.permission.INSTALL_PACKAGES" />
    <permission name="android.permission.INTERACT_ACROSS_USERS" />
</privapp-permissions>

Now rebuilding yet again, with this, the GSI is a step closer to booting!

This error may be a non-issue if I didn’t try to use the Superuser app but I really want to include it for fun

1 Like

Here’s the alpha of this GSI, it is booting and seems to be fully functional.

User note: This GSI is based on a (barely) custom Lineage 21, if you can use Lineage you can use this GSI.

This GSI may also be used to update ANY existing phone’s /e/OS to 2.7

Instructions if coming from Lineage21 :

Flash Lineage according to Lineage instructions

Wait until Lineage boots, then reboot to recovery.

For both Lineage and existing /e/OS users:

Enter Fastboot via recovery and enter the following commands:

fastboot erase system

fastboot flash system system.img

That’s it, reboot to /e/OS

3 Likes

For me, a custom GSI is particularly interesting if there is no custom ROM like LineageOS, crDroid & Co. for the device in question. This primarily affects devices with SoC such as MediaTek Helio + Dimensity, HiSilicon Kirin, Unisoc Tiger.

My current almost perfect solution for a MediaTek Device:

If you’d be willing to test this GSI build and provide adb logcat I could definitely bring it up for your device.

It seems like it will boot on my Pixel 6a using a stock ROM as a base sans the superuser error which requires a full rebuild, because the stock ROM doesn’t have permissions to execute it.

I will do that tonight and will have results tomorrow.

The issue for me is basically this: Google’s OS for Pixel is not the same as typical AOSP, and it is not possible to flash a GSI rom using their standard fastboot; the fastboot used must be Lineage or /e/OS (they are the same basically)

So to test my GSI builds under pixel I must flash the vendor, boot.img and vbmeta from Lineage recovery, then flash the system.

This is not representative of real-world conditions for flashing a GSI, I’m aware a GSI is available for Pixel 6a and it is possible that I could use that as a base to test with, but it is only available via their flashing tool as far as I know.

Keep in mind the GSI I produced is version 0.01, I need to determine what changes need to be made to the codebase and the only way to do this outside of my Pixel is real world feedback and adb logcat so I can change source issues as they arise.

@Null, I’m basically willing to support you and test your GSI. I’ve numerous test devices available.


Test N°1

Motorola Moto G62 5G XT2223-1
SoC: Qualcomm SM4350-AC Snapdragon 480+ 5G
Stock Android 13 Security: Nov. 2024
No custom recovery, no LineaageOS

/e/OS-U 2.7 GSI boots up to the animated e-logo. The bouncing dot bounces endlessly, and - nothing else happens.


Counter-test: iodéOS 5.8 GSI (based on LineageOS by @AndyYan) works flawlessly including OTA update.


Let’s keep going, even if it’s time-consuming and exhausting …

I believe you need Android 14 for this to work properly, I will build a Android 13 GSI for you tonight

1 Like

I’ve been eagerly waiting for a /e/OS-T (A13) for months.

Can you boot any of Andy’s Lineage GSIs?

Test N°2

Nothing Phone (1) A063 spacewar
SoC: Qualcomm SM7325-AE Snapdragon 778G+ 5G
NothingOS 2.6 (A14) Security: Nov. 2024
No custom recovery, no LineaageOS; no /e/OS

It’s the same scenario as in Test N°1: /e/OS-U 2.7 GSI boots up to the animated e-logo. The bouncing dot bounces endlessly, and - nothing else happens.


Counter-test N°1: VoltageOS 3.7 GSI (EOL) with build-in microG boots into the Voltage logo and exits again in a flash = bootloop.

Counter-test N°2: iodéOS 5.8 GSI with build-in microG works (within the scope of its possibilities (without support of Glyph) including OTA update.

I still haven’t patched the source tree to be compatible with vendor-specific hardware.

The 0.01 version is meant to ensure that everything works correctly on Lineage devices, before doing so.

In any event, I’m taking a break from it to slam out a A13 version which I will patch for generic devices but I cannot test it, and I will need adb logcat feedback from it if possible because if it doesn’t boot I need to know the reason why

Does adb logcat also work if /e/OS-U 2.7 GSI system does not boot at all?