[Android Software Development] :
​

Welcome in this new tutorial! In this thread, i'll try to explain you how to create a device-tree. This is one of the most important part in the rom porting. So let's start right now!​

Warning: i took as example an Samsung phone and 7.0 rom.

1. Understanding the device tree structure

Let's begin with folders :

Bluetooth | This folder contains some files and C headers to define Bluetooth features of the phone (default Bluetooth name, Bluetooth library name (.hcd), WBS forcing, low energy support)

CMHW | CyanogenMod Hardware, it contains few Java classes to make some basic features work such as vibrator intensity, display color calibration, etc...

Configs | This folder contains sub-folders that contains few files from stock firmware for audio, WiFi, GPS, key-layout, NFC, etc... They are sometimes edited or kept stock (audio is often edited)

Include | This contains all C headers that needs to be edited from phone hardware (example: samsung_audio.h from hardware/samsung/, this is edited to define good number of capture, speakers devices.)

Init | Init folder contains a simple C or C++ function to select the good variant of the phone that runs the ROM. (example: SM-A310FD is dual-sim. So this function will enable dual-sim if it detects the FD model)

Libshims | This is an optional folder, all devices don't obligatory need it. It contains empty functions (abstract) like an API for phone features (Wikipedia)

Overlay | This folder is a important part. It contains XML configuration files for framework, apps, etc... It's important to keep framework aligned with stock one (using apktool)

Ramdisk | This folder contains as base the stock ramdisk extracted from kernel. It will be edited depending of permissions, services, etc...

RIL | This contain a Java function to make work the radio features (switching network, handle call, detect SIM card, etc...)

Sepolicy | (not on photo) This folder contains .te files that contains permissions for camera, audio, apps, etc...

Files :

Android.mk | This makefile is present in a lot of folder, it just makes the device-tree detectable by the building script if the user called the command with the good device name to build

BoardConfig.mk | This second makefile is one of the most important, it contains all board defines (partition size, include path, overlay path, CPU, SoC, etc...)

Lineage.mk | This file is the first read by the building script, it just contains the product name, codename, manufacturer but also if it's a phone or a tablet and it link the device.mk

device.mk | This file contains all package, apps, permissions and libraries to use or to copy. It also contain phone size to build apps (ex: xhdpi)

extract-files.sh + setup-makefiles.sh | There's shell script are called to create a vendor (they pull needed files from proprietary-files.txt from ADB into a vendor folder)

proprietary-files.txt | This text file have one file on each line. It determine all needed files from stock firmware to make AOSP work (audio libraries, graphical lib (such as OpenGL, MALI driver), etc...)

system.prop | This file contains properties that will be copied in the build.prop. It contains some settings such as RIL classes/libraries/support, WLAN interface to use, display size, etc...)

2. Basic files

Now we finished explaining the structure. Let's get ready for the basic files​

A. The Android.mk

# Here we define a variable called "LOCAL_PATH" that just contain the path to the device tree (ex: /device/samsung/a3xeltexx)
LOCAL_PATH := $(call my-dir)

# Here we open an if statement that will be true if the user requested to build that device.
ifneq ($(filter a3xeltexx,$(TARGET_DEVICE)),)

# Here we call other makefiles in the device-tree
include $(call all-subdir-makefiles,$(LOCAL_PATH))

# Here we clean variables
include $(CLEAR_VARS)

# Here we close the if statement.
endif

B. The Lineage.mk

# Note: the lineage.mk can also be called slim.mk, pa.mk, aoscp.mk, etc...
# Depending on the ROM to build. LineageOS based roms will use lineage.mk

# Inherit device configuration
$(call inherit-product, device/samsung/a3xeltexx/device.mk)

# Inherit from the common Open Source product configuration
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)

# Inherit common CM phone.
$(call inherit-product, vendor/cm/config/common_full_phone.mk)

# Set those variables here to overwrite the inherited values.
PRODUCT_NAME := lineage_a3xeltexx
PRODUCT_DEVICE := a3xeltexx
PRODUCT_BRAND := samsung
PRODUCT_MANUFACTURER := samsung

C. Proprietary-files.txt

# Note: the proprietary-files.txt contains files needed to make the phone or features working.
# Consider below values as example.

# Scaler CSC
lib/libexynosscaler.so
lib/libexynosgscaler.so
lib/libexynosutils.so

# Gralloc
lib/hw/gralloc.exynos5.so

# GPS
bin/gpsd
bin/gps.cer
lib/hw/gps.default.so
lib/libwrappergps.so
lib/libfloatingfeature.so

# Graphics
vendor/lib/egl/libGLES_mali.so

# etc.... There is much more files to pull :D

D. System.prop

# Note: again, consider below values as example.
# Note 2: system.prop need to define HWUI and Dalvik values that you can find in stock firmware.

# media
media.stagefright.legacyencoder=1
media.stagefright.less-secure=1

# Graphics
ro.opengles.version=196609
ro.sf.lcd_density=320

# HWC
debug.hwc.force_gpu=1

3. The BoardConfig

Let's now talk about the BoardConfig.mk​

# This is a example. It's uncomplete.
# You can refer to GitHub to see complete BoardConfig.mk

# Platform
# Here we define our manufacturer, based board (exynos5), target board (exynos7580), our slsi variant
BOARD_VENDOR := samsung
TARGET_BOARD_PLATFORM := exynos5
TARGET_SOC := exynos7580
TARGET_SLSI_VARIANT := cm

# Arch
# Here we define our CPU
TARGET_BOARD_SUFFIX := _32
TARGET_ARCH := arm
TARGET_ARCH_VARIANT := armv7-a-neon
TARGET_CPU_ABI := armeabi-v7a
TARGET_CPU_ABI2 := armeabi
TARGET_CPU_VARIANT := cortex-a53
TARGET_CPU_CORTEX_A53 := true

# Bootloader
TARGET_BOOTLOADER_BOARD_NAME := universal7580

# Define device codename we support
TARGET_OTA_ASSERT_DEVICE := a3xelte,a3xeltexx,a3xelteub,a3xeltedo,a3xeltekx

# Define device-tree path
DEVICE_PATH := device/samsung/a3xeltexx

# Include path
TARGET_SPECIFIC_HEADER_PATH += $(DEVICE_PATH)/include

# Bluetooth
BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(DEVICE_PATH)/bluetooth

# Hardware
BOARD_HARDWARE_CLASS += $(DEVICE_PATH)/cmhw

# Init
TARGET_INIT_VENDOR_LIB := libinit_sec
TARGET_UNIFIED_DEVICE := true

# Kernel
TARGET_KERNEL_CONFIG := lineage-a3xeltexx_defconfig
TARGET_KERNEL_SOURCE := kernel/samsung/a3xeltexx
TARGET_KERNEL_ARCH := arm64
TARGET_KERNEL_HEADER_ARCH := arm64

# Extracted with libbootimg
BOARD_CUSTOM_BOOTIMG_MK := hardware/samsung/mkbootimg.mk
BOARD_KERNEL_SEPARATED_DT := true
BOARD_MKBOOTIMG_ARGS := --kernel_offset 0x00008000 --ramdisk_offset 0x01000000 --tags_offset 0x00000100 --board SRPOJ08A000KU
TARGET_CUSTOM_DTBTOOL := dtbhtoolExynos

# Partitions sizes
BOARD_HAS_NO_MISC_PARTITION := false
TARGET_USERIMAGES_USE_EXT4 := true
BOARD_BOOTIMAGE_PARTITION_SIZE := 33554432	# 32MB
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 39845888	# 38MB
BOARD_CACHEIMAGE_PARTITION_SIZE := 209715200	# 200MB
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3145728000	# 3GB
BOARD_USERDATAIMAGE_PARTITION_SIZE := 12096372736	# 11GB
BOARD_FLASH_BLOCK_SIZE := 4096

# .dat compression
BLOCK_BASED_OTA := true

# PowerHAL
TARGET_POWERHAL_VARIANT := samsung

# Properties
TARGET_SYSTEM_PROP += $(DEVICE_PATH)/system.prop

# Charger
BACKLIGHT_PATH := /sys/devices/14800000.dsim/backlight/panel/brightness

# Recovery
TARGET_RECOVERY_FSTAB := $(DEVICE_PATH)/ramdisk/fstab.samsungexynos7580

# Radio
BOARD_RIL_CLASS := ../../../$(DEVICE_PATH)/ril
BOARD_MODEM_TYPE := tss310

# NFC
BOARD_NFC_CHIPSET := pn547

# Here we include the vendor
-include vendor/samsung/a3xeltexx/BoardConfigVendor.mk