LineageOS 15.1 for Axon 7 (A2017G): Using Docker to Build from Source

  • Touch on topic Qualcomm Snapdragon 820 MSM8996 requirements for unlocking the bootloader and enabling Fastboot for certain firmware variants.
  • Outline the procedure for installing/flashing the build onto the physical device.

Axon 7 (A2017G) — Key Hardware Details

Here are some of the key hardware details for the Axon 7 (A2017G) variant:

  • CPU: 2x Dual Core Kryo (total of 4 cores)
  • Architecture: 64 bit armv8-a
  • GPU: Qualcomm Adreno 530
  • Built in Storage Type: UFS 2.0
  • RAM: 4GB LPDDR4

Host Environment Requirements

Using a Linux host running docker is preferable, and likely to give a better chance of successfully building LineageOS15.1 using the docker image.

Build and Configure Docker Image

The components required to build the docker image can be found within the following Git repo. The README.md within the repo, contains further details on usage/components.

Clone Docker Repo onto Host Machine

The commands below clone the repo to target: $HOME/docker_repo/dev-docker-android.

$ cd $HOME
$ mkdir docker_repo

$ cd $HOME/docker_repo/

$ git clone \
https://github.com/tonys-code-base/dev-docker-android.git

Edit Local Repo gitconfig Details

A git identity is required for cloning the LineageOS15.1 repo source. You can configure the Dockerfile to reflect your preferred git identity. The existing docker image treats the git profile below as "system wide" within containers derived from the image (i.e. target location within the container/image at/etc/gitconfig).

[user]
name = Your Name
email = me@example.com

Building the Docker Image

Run the following to create the image android-dev :

$ cd $HOME/docker_repo/dev-docker-android

$ docker build --build-arg userid=$(id -u) \
--build-arg groupid=$(id -g) \
--build-arg username=$(id -un) -t android-dev .

Create Host Directories for LineageOS 15.1 Build

Lineage Project Location

Just about all of the activities involved in the build process will be performed from within a docker container. To ensure the project components are persisted on the host (and not purged for cases such as container/image pruning), a common host:container directory should be established. This directory can later be mounted when running the docker image.

$ mkdir $HOME/lineage15

Ad-hoc Files Location

A similar setup to that of the above is recommended for accessing/sharing non-specific build/project components. This is assumed to be:

$ mkdir $HOME/lineage_dloads

Run Docker Container

  • We spin up a container using our image as follows:
$ sudo docker run -it --rm --privileged \
--cap-add=ALL \
-v $HOME/lineage15:/lineage15 \
-v $HOME/lineage_dloads:/lineage_dloads \
android-dev
|-------------------------------------------|
| host | container |
-----------------------|--------------------|
| $HOME/lineage15 | /lineage15 |
| $HOME/lineage_dloads | /lineage_dloads |
--------------------------------------------|

Initialise and Sync LineageOS15.1 Repo

Initialise

  • Change into our project directory. This will be the top level of our build (in Android’s official documentation, it is often referred to as $ANDROID_BUILD_TOP).
$ cd /lineage15
$ repo init -u https://github.com/LineageOS/android.git -b \
lineage-15.1

Sync

  • To download/sync local repo from the remote, run the following:
$ cd /lineage15
$ repo sync

Add Axon 7 Device to the Build

By now your top level project folder, $ANDROID_BUILD_TOP (/lineage15) should contain the Lineage15.1 code branch. We still need to fetch the device specific repo.

Fix Device Combo Menu Choice

The file /lineage15/vendor/lineage/vendorsetup.sh that was fetched from the 15.1 base repo contains a reference to a remote file path (https://raw.githubusercontent.com/LineageOS/hudson/master/lineage-build-targets) from which device target build details are sourced. This remote file no longer has an entry for Lineage15.1, so for the purposes of consistency, we can replace contents of existing file /lineage15/vendor/lineage/vendorsetup.sh to point to /lineage-build-targets.txt:

for combo in $(cat /lineage-build-targets.txt | sed -e 's/#.*$//' | grep lineage-15.1 | awk '{printf "lineage_%s-%s\n", $1, $2}')
do
add_lunch_combo $combo
done

Product/Device Specific Code

We need to ensure that we have all the appropriate make/config files & their dependencies. These include a directory structure for our device configuration ($ANDROID_BUILD_TOP/device/<company-name>/<device-name>).

/lineage15/device
├── common
├── generic
├── google
├── lineage
├── qcom
└── sample
$ cd /lineage15
$ source build/envsetup.sh
  • To choose the product we wish to build for:
$ breakfast
including vendor/lineage/vendorsetup.sh

You're building on Linux

Lunch menu... pick a combo:
1. full-eng
2. lineage_axon7-userdebug
Which would you like? [aosp_arm-eng]
  • Once done, part of the output log from breakfast is shown below. You will notice in the output that the Axon 7 specific code is retrieved from remote repo https://github.com/LineageOS/android_device_zte_axon7, and the branch being checked out is lineage-15.1.
build/core/product_config.mk:238: *** Can not locate config makefile for product "lineage_axon7".  Stop.
Device axon7 not found. Attempting to retrieve device repository from LineageOS Github (http://github.com/LineageOS).
Found repository: android_device_zte_axon7
Default revision: lineage-15.1
Checking branch info
Checking if device/zte/axon7 is fetched from android_device_zte_axon7
...
Using default branch for android_device_zte_axon7
Syncing repository to retrieve project.
...
repo sync has finished successfully.
Repository synced!
Looking for dependencies in device/zte/axon7
Adding dependencies to manifest
Checking if device/qcom/common is fetched from android_device_qcom_common
Adding dependency: LineageOS/android_device_qcom_common -> device/qcom/common
...
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.1.0
LINEAGE_VERSION=15.1-20200629-UNOFFICIAL-axon7
TARGET_PRODUCT=lineage_axon7
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPM1
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=kryo
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.3.0-61-generic-x86_64-with-Ubuntu-19.10-eoan
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=OPM7.181205.001
OUT_DIR=/lineage15/out
AUX_OS_VARIANT_LIST=
============================================
/lineage15/device/zte
└── axon7
$ ls /lineage15/device/zte/axon7/*.mk
Android.mk BoardConfig.mk device.mk lineage.mk

Extracting Proprietary Blobs

Proprietary blobs are files/modules that are required for the build to successfully complete.

Extracting from Axon 7 Device with LineageOS15.1 Installed

To extract blobs from an Axon 7 with LineageOS already installed and running:

  • Attach your Axon 7 to your host via USB.
  • Ensure that the ADB Debug Bridge is enabled via your device settings: Developer Options -> Debugging -> Android Debugging.
  • Run the following to bring up the docker container:
$ sudo docker run -it --rm --privileged \
--cap-add=ALL \
-v $HOME/lineage15:/lineage15 \
-v $HOME/lineage_dloads:/lineage_dloads \
android-dev
$ cd /lineage15
$ source build/envsetup.sh
$ cd /lineage15/device/zte/axon7/
$ ./extract-files.sh

Extracting from LineageOS15.1 Flashable Zip

The method that will be described is based on a flashable zip that is classified as Blocked Based:

  • From within the docker container, check to ensure this in fact is a Block-based zip by checking that the system* suffixes are dat/dat.br, the system folder is nearly empty and that system.transfer.list exists:
$ cd /lineage_dloads
$ unzip -l lineage-15.1-20200622-UNOFFICIAL-axon7.zip | \
grep -i -e system -e vendor

...
system.new.dat.br
system.transfer.list
system/build.prop
...
vendor.new.dat.br
vendor.transfer.list
...
  • Create working directory for the extract process:
$ cd /lineage15
$ mkdir system_dump
$ cd system_dump
$ unzip /lineage_dloads/lineage-15.1-20200622-UNOFFICIAL-axon7.zip  system.transfer.list system.new.dat*

$ unzip /lineage_dloads/lineage-15.1-20200622-UNOFFICIAL-axon7.zip vendor.transfer.list vendor.new.dat*
$ brotli --decompress --output=system.new.dat system.new.dat.br
$ brotli --decompress --output=vendor.new.dat vendor.new.dat.br
$ python /usr/local/bin/sdat2img.py system.transfer.list system.new.dat  system.img

$ python /usr/local/bin/sdat2img.py vendor.transfer.list vendor.new.dat vendor.img
  • Create mount point and mount system.img:
$ mkdir system
$ sudo mount system.img system/
$ sudo rm system/vendor
$ sudo mkdir system/vendor
$ sudo mount vendor.img system/vendor/
$ cd /lineage15/device/zte/axon7
$ sudo ./extract-files.sh /lineage15/system_dump/
$ sudo umount /lineage15/system_dump/system/vendor/
$ sudo umount /lineage15/system_dump/system/
$ rm -fr /lineage15/system_dump

Build LineageOS15.1

  • Kick off the build by running:
$ cd /lineage15
$ brunch axon7
  • Once the build has completed successfully, the output should display the location and name of the LineageOS15.1 flashable zip produced by the build:
Package Complete: 
/lineage15/out/target/product/axon7/lineage-15.1-<YYYYMMDD>-UNOFFICIAL-axon7.zip

#### build completed successfully (04:42:23 (hh:mm:ss)) ####

Axon 7 A2017G — State Prior to Flashing LineageOS15.1

Note the instructions below were tested on an Axon 7, A2017G variant. The testing was carried out on a device that was in the following state prior to flashing the build onto the device:

  • Build Number — ZTE A2017GV1.2.0B10
  • Bootloader — LOCKED
  • SanDisk 32GB SD Card for storing flash files

Unlock Bootloader & Enable Fastboot

$ adb reboot bootloader
$ fastboot devices -l
...
488f9532 fastboot
$ fastboot oem unlock

Unable to Boot into Bootloader/Fastboot

If you still can’t boot into the bootloader, then it's likely that updates to partitions residing on the Qualcomm chipset embedded storage (aka UFS), would need to be updated. Generally, the partitions affected are named aboot and/or fbop . This method requires booting into Emergency Download Mode (EDL), and flashing these partitions using a proprietary programmer, which utilises the firehose protocol to access the Snapdragon 820 MSM8996 SoC flash memory. These programmers have made their way onto various online sites and come packaged in toolkits for unlocking, as well as full EDL image downloads.

filename="emmc_appsboot.mbn" label="aboot" 
filename="fastboot.img" label="fbop"

Install Custom Recovery (TWRP)

In order to be able to prepare the device for LineageOS15.1, we’ll need a custom recovery.

  • Ensure you are in fastboot mode, if you are not, then run adb reboot bootloader to reboot the device into fastboot mode.
  • Run the following to ensure your device is listed:
$ fastboot devices -l
...
488f9532 fastboot
$ fastboot flash recovery twrp-3.3.1-0-ailsa_ii.img
  • From TWRP, perform a “Wipe--> "Advanced Wipe" and tick "Dalvik/ART Cache", "Data", "Cache" and "System". Perform a "format data", if you had encrypted storage.
  • You will need to stay in recovery mode for the next section ("Installing a Universal Bootstack")
  • If you accidentally exit recovery mode boot back into recovery as follows: a) Long pressing Power to switch off the device.
    b) Once the device has switched off, simultaneously hold down Power + Volume Up.
    c) When the ZTE logo appears, release the Power Button and continue holding the.Volume Up.
    d) Once the TWRP recovery screen appears, release the Volume Up button.

Install Universal Oreo Bootstack, Modem and LineageOS15.1

Before we can flash our build of LineageOS15.1, we will need a compatible bootstack (elements of the firmware, i.e. in this case, the phone’s modem and bootloader) that will support loading LineageOS15.1.

Bootstack

Modem (for A2017G)

  1. Untick “Reboot after installation is compete” and swipe to flash.
  2. Repeat the above steps for the A2017G_OreoModem.zip file.
  3. Now reboot into TWRP recovery again with the new bootstack/modem. TWRP has an option to select booting back into recovery. During the reboot, accept any prompt/warning relating to corrupt/unlocked bootloader by pressing the "Power" button.
  4. Once back in TWRP, you can finally flash your lineage-15.1-<YYYYMMDD>-UNOFFICIAL-axon7.zip.
  5. Perform a Wipe cache/Dalvik.
  6. Reboot the system, accept bootloader prompts regarding “unlocked/corrupt” bootloader by pressing the “Power” button.
  7. Give the initial boot a few minutes to load. If you don’t see the LineageOS splash screen after a few minutes, power off the device by long pressing Power key and let it reboot once more.
LINEAGE_VERSION=15.1-20200629-UNOFFICIAL-axon7

Final Points

If you’ve stumbled on this article, I hope you’ve found it to be informative. If you come across inaccurate details, feel free to comment and I will update as required.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store