[Galaxy A3, A5, A7, A8, A9 General] Cerres1:
﻿Hi,

I tried porting LinageOS 14 to the Samsung Galaxy A3(2016) SM-A310F and this is a summary of my endeavors. The end result will be a flashabel .zip-file, also called OTA-package. I should say, that the resulting image does not yet boot!

There is little information on how to exactly port LineageOS to a new device, so I had to read a bit:

https : // source . android . com / source/ initializing . html

http : // web . archive . org /web / 2 0161224192644 / https :// wiki . cyanogenmod . org / w / Doc:_porting_intro

http : // web . archive . org / web / 20161224194055 / https : // wiki . cyanogenmod . org / w /Local_manifest

http : // wiki . lineageos . org / devices/ hero2lte /build

http : // www . trcompu . com / MySmartPhone / AndroidKitchen / Breakfast -Brunch -Lunch . html

http : // wiki . lineageos . org /signing_builds . html # generating-and-signing -target-files.

We start with installing TWRP onto our phone and rooting it afterwards. Now we look around and inspect the partition layout. The following command are run on the device with the help of adb (sudo apt-get install adb):

adb shell
su

root@a3xelte:/ # ls -al /dev/block/platform/13540000.dwmmc0/by-name/
lrwxrwxrwx root root 2017-03-06 17:48 BOOT -> /dev/block/mmcblk0p10
lrwxrwxrwx root root 2017-03-06 17:48 BOTA0 -> /dev/block/mmcblk0p1
lrwxrwxrwx root root 2017-03-06 17:48 BOTA1 -> /dev/block/mmcblk0p2
lrwxrwxrwx root root 2017-03-06 17:48 CACHE -> /dev/block/mmcblk0p21
lrwxrwxrwx root root 2017-03-06 17:48 CARRIER -> /dev/block/mmcblk0p8
lrwxrwxrwx root root 2017-03-06 17:48 CDMA-RADIO -> /dev/block/mmcblk0p13
lrwxrwxrwx root root 2017-03-06 17:48 CPEFS -> /dev/block/mmcblk0p4
lrwxrwxrwx root root 2017-03-06 17:48 DNT -> /dev/block/mmcblk0p16
lrwxrwxrwx root root 2017-03-06 17:48 EFS -> /dev/block/mmcblk0p3
lrwxrwxrwx root root 2017-03-06 17:48 HIDDEN -> /dev/block/mmcblk0p22
lrwxrwxrwx root root 2017-03-06 17:48 OTA -> /dev/block/mmcblk0p12
lrwxrwxrwx root root 2017-03-06 17:48 PARAM -> /dev/block/mmcblk0p9
lrwxrwxrwx root root 2017-03-06 17:48 PERSDATA -> /dev/block/mmcblk0p18
lrwxrwxrwx root root 2017-03-06 17:48 PERSISTENT -> /dev/block/mmcblk0p17
lrwxrwxrwx root root 2017-03-06 17:48 RADIO -> /dev/block/mmcblk0p14
lrwxrwxrwx root root 2017-03-06 17:48 RECOVERY -> /dev/block/mmcblk0p11
lrwxrwxrwx root root 2017-03-06 17:48 RESERVED2 -> /dev/block/mmcblk0p19
lrwxrwxrwx root root 2017-03-06 17:48 SYSTEM -> /dev/block/mmcblk0p20
lrwxrwxrwx root root 2017-03-06 17:48 TOMBSTONES -> /dev/block/mmcblk0p15
lrwxrwxrwx root root 2017-03-06 17:48 USERDATA -> /dev/block/mmcblk0p23
lrwxrwxrwx root root 2017-03-06 17:48 m9kefs1 -> /dev/block/mmcblk0p5
lrwxrwxrwx root root 2017-03-06 17:48 m9kefs2 -> /dev/block/mmcblk0p6
lrwxrwxrwx root root 2017-03-06 17:48 m9kefs3 -> /dev/block/mmcblk0p7

Also, take note of the CPU

root@a3xelte:/ # cat /proc/c

cgroups cmdline consoles cpuinfo crypto
root@a3xelte:/ # cat /proc/cpuinfo
Processor : AArch64 Processor rev 3 (aarch64)
processor : 0
Features : fp asimd aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 3

Hardware : SAMSUNG Exynos7580

We also need to find the block-size:

root@a3xelte:/ # df -k
This will tell us 4.0 K block size.
Note: if you install parted on the device it will tell you:

Model: MMC AJNB3R (sd/mmc)
Disk /dev/block/mmcblk0: 15758000128B
Sector size (logical/physical): 512B/512B
Partition Table: gpt

I started with a fresh install of Ubuntu 14.04 LTS 64-Bit, as described by Google. If you use some newer Ubuntu, there may be some problems with packages. I did not suceed with e.g. 16.10.

Install some basic packages:

sudo apt-get install git-core gnupg flex bison gperf build-essential \
zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache \
libgl1-mesa-dev libxml2-utils xsltproc unzip

Install LinageOS packages:

sudo apt-get install bc bison build-essential curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-gplv2-dev lib32z1-dev libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libwxgtk2.8-dev libxml2 libxml2-utils lzop openssl-dev pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev

Install OpenJDK-8 (remove openjdk-7 first!)

sudo apt-get autoremove openjdk-7-jre

sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk

Download the repo command

replace XXXX with https : // storage.googleapis.

curl XXXXcom/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

Prepare you bash environment:

Edit the file ~/.profile (it is a hidden file in your home directory). You can make it visible in the Ubuntu file manager (called Nautilus) by pressing CTR+H.

Add this to the end of the file.

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi

export USE_CCACHE=1

export ANDROID_JACK_VM_ARGS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx8G"

The last line will increase the memory for the build process with 'jack'. If the size -Xmx8G is too small (here 8 gigabytes), the build process will fail.

Restart you terminal window for the changes to take effect, or run

source ~/.profile

Download LineageOS

Preparation

replace XXX with https : // github.com

mkdir -p ~/bin
mkdir -p ~/android/lineage
cd ~/android/lineage
repo init -u XXX/LineageOS/android.git -b cm-14.1

Start the download with:

repo sync

If it fails, just start it again. This will be several Gbs and take a few hours.

If everything goes well, we can download some more files specific to our device a3xelte. We are lucky and there is already some GitHub-Repository Exynos 7580 with device-specific code, I think maintained by aapav01.

Create or open the file android/lineage/.repo/local_manifests/roomservice.xml.

Replace it with the following content and save the file:

<manifest>
<project name="Exynos7580/android_device_samsung_a3xeltexx" path="device/samsung/a3xeltexx" remote="github" revision="cm-14.1"/>
<project name="Exynos7580/android_device_samsung_exynos7580-common" path="device/samsung/exynos7580-common" remote="github" revision="cm-14.1"/>
<project name="Exynos7580/android_vendor_samsung_a3xeltexx" path="vendor/samsung/a3xeltexx" remote="github" revision="cm-14.1"/>
<project name="LineageOS/android_hardware_samsung_slsi-cm_exynos5" path="hardware/samsung_slsi-cm/exynos5" remote="github" revision="cm-14.1"/><project name="Exynos7580/android_hardware_samsung_slsi-cm_exynos7580" path="hardware/samsung_slsi-cm/exynos7580" remote="github" revision="cm-14.1"/>
<project name="LineageOS/android_external_stlport" path="external/stlport" remote="github"/>
<project name="LineageOS/android_hardware_samsung" path="hardware/samsung" remote="github"/>
<project name="LineageOS/android_hardware_samsung_slsi-cm_exynos" path="hardware/samsung_slsi-cm/exynos" remote="github"/><project name="LineageOS/android_hardware_samsung_slsi-cm_openmax" path="hardware/samsung_slsi-cm/openmax" remote="github"/>
</manifest>

Run the repo synch command again in the root of the LinageOS folder:

cd ~/android/lineage
repo sync

I should mention, that there is a repository https : // github . com / Exynos7580/android_kernel_samsung_a3xelte, but I did not use that. You could try to use this, if it will give you better results.

I instead, choose to try to use the raw Samsung kernel source. To do that, got to http :/ opensource. samsung . com/reception .do and type 'SM-A310F' in the search box. I choose to download the Android 6.0.1 files SM-A310F_MEA_MM_Opensource.zip

Extract it to some place, extract again resulting the Kernel.tar.gz.

Create the directory ~/android/lineage/kernel/samsung/ and copy the just extracted 'kernel'-directory to it. Rename the directory to a3xeltexx, so that you now have the kernel in ~/android/lineage/kernel/samsung/a3xeltexx.

Edit the device properties

go to device/samsung/a3xeltexx

and edit the files BoardConfig.mk and lineage.mk to your liking and do the same with /device/samsung/exynos7580-common/BoardConfigCommon.mk.

I don't know what the right values are, but for example, I set the number of SIM-cards to match my phone:

SIM_COUNT := 1

Also adjust the name of the kernel configuration file.

I should mention that for the SM-A310F the following values are defined in the original build.prop, and therefore this device should be called 'a3xelte' instead of 'a3xeltexx' according to the LineageOS nomenclature rules. But I did not yet change all the directroy names. That is left to when the image will boot up.

ro.product.model=SM-A310F
ro.product.brand=samsung
ro.product.name=a3xeltexx
ro.product.device=a3xelte
ro.product.board=universal7580

Extract proprietary blobs

I choose to extract the binary blobs from running phone, not a firmware image. To do so, you need have a rooted phone with adb debug enabled and granted adb root permission.

I needed to edit the file ~/android/lineage/device/samsung/a3xeltexx/extract-files.sh to look like this

...
if [ "$SRC" = "adb" ]; then
echo $DEST
set +e
# Try CM target first
adb pull /system/$DEST $2/$DEST
# if file does not exist try OEM target
if [ "$?" != "0" ]; then
echo "Try using OEM target"
adb pull /system/$FILE $2/$DEST
fi
set -e
if [ ! -f $2/$DEST ]; then
echo "File not yet copied -> try as root!"

adb shell mkdir -p /sdcard/tmp
adb shell mkdir -p /sdcard/tmp/$DIR
echo "Copy to temp location"
adb shell su -c "cp /system/$FILE /sdcard/tmp/$FILE"
adb pull /sdcard/tmp/$FILE $2/$DEST
adb shell rm /sdcard/tmp/$FILE
adb shell rm /sdcard/tmp/$DIR
fi
...

then run

cd ~/android/lineage/device/samsung/a3xeltexx
./extract-files.sh

Fix build-problems

The kernel will not build successfully right now, but we can help it compile, if we create a bunch of empty directories. Must be done after each cleaning of the build tree.

Create a new file ~/android/linage/cerres-prepare-kernel.sh and paste the following lines

mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/security/tima_uevent
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/drivers/gud/gud-exynos7580/MobiCoreDriver/platforms
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/drivers/gud/gud-exynos7580/MobiCoreDriver/platforms/EXYNOS_7580_STD
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/firmware/tsp_synaptics
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/firmware/tsp_atmel
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/firmware/tsp_stm
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/drivers/media/platform/exynos/fimc-is2/hardware/api
mkdir -p out/target/product/a3xeltexx/obj/KERNEL_OBJ/drivers/muic/universal

make it executable and run it:

cd ~/android/lineage
chmod a+x cerres-prepare-kernel.sh
./cerres-prepare-kernel.sh

Fix include errors

For some reason, unknown to me, some required header files are not copied to out/target/product/a3xeltexx/obj/KERNEL_OBJ/usr/include.

Go to kernel/samsung/a3xeltexx/include/uapi/linux and find the files

videodev2_exynos_camera.h
videodev2_exynos_camera_ext.h
videodev2_exynos_media.h

and copy them to these newly created directories:

~/android/lineage/hardware/samsung_slsi-cm/exynos/include/linux
~/android/lineage/hardware/samsung_slsi-cm/exynos5/include/linux

To start building type:

cd ~/android/lineage
. build/envsetup.sh
lunch lineage_a3xeltexx-userdebug
mka target-files-package dist

The build will run now for several hours. For my machine, with only 4GB of ram this will take around 24 hours. Also, the mka command uses too many threads for me (the build script would loose connection to the jack server), so I had to reduce the number of threads by editing the file /home/cerres/android/system/vendor/cm/build/envsetup.sh (look for the make command!)

Generating the flashable zip-package

Create key-pairs for your own use:

subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media; do \
./development/tools/make_key ~/.android-certs/$x "$subject"; \
done

Sign the target files:

cd ~/android/lineage
croot
./build/tools/releasetools/sign_target_files_apks -o -d ~/.android-certs \
out/dist/*-target_files-*.zip \
out/dist/signed-target_files.zip

The signing doesn't currently work, because this error is generated:

ERROR: couldn't find ro.build.date.utc in build.prop

I'll have to figure out, how to fix that. However, we can create an OTA package from the unsigend target files. Just modify the file name accordingly.

And, finally, build the OTA-package:

./build/tools/releasetools/ota_from_target_files -k ~/.android-certs/releasekey \
--block --verbose --no_prereq \
out/dist/signed-target_files.zip \
out/signed-ota_update.zip

Copy the file out/signed-ota_update.zip to an extenal sd-card and flash it using TWRP -> boot loop.

Points for future improvements

To debug boot problems in the kernel ('boot-loop') it would be wise to enable logging in the kernel config:

CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_RAM=y

Try building with integrated root support

create a .sh file with the following content and run it before building:

export WITH_SU=true

Final remarks:

some problems could be due to the fact, that I'm trying to use the Samsung kernel for 6.0.1 with Android 7.0 (LineageOS 14).

I hope this post helps you getting started to play around with your own code-base.