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...
- 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
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
# 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
# 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
# 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
# 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