Learn how you can port Custom ROM to an Android Device

Sudheer Gurram Nov 10 - 7 min read

Audio : Listen to This Blog.

Objective

This article serves as a guide for use case of porting custom ROM to android device, using the android open source project (AOSP). If you have an older device that isn’t receiving updates anymore and you want to run the latest version of Android, a custom ROM is just the way to go. CyanogenMod is the most popular ROM for this purpose.
Reasons for custom ROM port

  1. Get the latest version of Android on your device, as many manufacturers do not update their old phones
  2. Replace Manufacturer Skin with a Stock Version of Android
  3. Eliminate bloatware apps (pre-installed by Carriers and Manufactures), which can clutter your system and waste disk space
  4. Add additional features and system tweaks like overclocking, customize settings, disable volume warning and more.
  5. Configure Application permissions

Prerequisites

This document assumes that the Build environment and android sources (AOSP) are installed and configured. The developer uses the build system for building the android image from the android sources and flash the image to the device.
Refer to following document for getting additional details on procuring and establishing the android environment
https://source.android.com/source/requirements.html

Porting steps:

Following steps describe the process involved in making a custom ROM for an Android device. Assuming the android source for interested/ latest version of Android is downloaded and build environment is configured, here are the high level tasks involved in the development process

  1. Adding the make files of device to the build system.
  2. Including the kernel sources for the device
  3. Building the custom ROM image and resolving the build issues
  4. Boot to recovery image and flashing the custom ROM
  5. Debugging the boot up issues, if any

Adding the make files of device to the build system

To port a new android version to the device, we need to include the device specific makefiles to android build system, Following steps describe how to set up product makefiles for a device. Nearly everything you need to do will be in the /device/[vendor]/[codename], /vendor/[vendor]/[codename], and /kernel/[vendor]/[codename] directories.

1. Create a device/<company_name>/<device_name> directory for your product.
The /device directory contains configuration settings and other code for particular devices. It is always good to adapt a directory for an existing device (look for a device that is based on the same platform) that is architecturally similar to the one you wish to port.

2. Create a device.mk Makefile that declares the files and modules needed for the device.
Here is a snapshot of the device.mk file for Samsung S4 device

LOCAL_PATH := device/samsung/i9500
# overlays
DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/overlay
# Boot animation
TARGET_SCREEN_HEIGHT := 960
TARGET_SCREEN_WIDTH := 540
# Ramdisk
PRODUCT_PACKAGES += \
fstab.universal5410 \
init.universal5410.rc \
init.universal5410.usb.rc \
init.universal5410.wifi.rc \
ueventd.universal5410.rc
# Recovery
PRODUCT_PACKAGES += \
init.recovery.universal5410.rc

3. Create a product definition Makefile to create a specific product based on the device.
Here is the snapshot of the i9500-vendor.mk file

# Inherit from the common Open Source product configuration
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
PRODUCT_NAME := samsung_i9500
PRODUCT_DEVICE := i9500
PRODUCT_BRAND := Android
PRODUCT_MODEL := AOSP on i9500
PRODUCT_MANUFACTURER := samsung
PRODUCT_RESTRICT_VENDOR_FILES := true
$(call inherit-product, device/samsung/i9500/i9500.mk)
$(call inherit-product-if-exists, vendor/samsung/i9500/i9500-vendor.mk)
PRODUCT_NAME := samsung_i9500
PRODUCT_PACKAGES += \
Launcher3

4. Create an AndroidProducts.mk file that points to the product’s Makefiles

PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/i9500.mk

5. Create a BoardConfig.mk Makefile that contains board-specific configurations.
Here is the snapshot of the BoardConfig.mk file.

LOCAL_PATH := device/samsung/i9500
BOARD_VENDOR := samsung
# Include path
TARGET_SPECIFIC_HEADER_PATH := $(LOCAL_PATH)/include
# Bootloader
TARGET_BOOTLOADER_BOARD_NAME := universal5410
TARGET_NO_BOOTLOADER := false
# Platform
TARGET_BOARD_PLATFORM := exynos5
TARGET_SOC := exynos5410
# Architecture
TARGET_ARCH := arm
TARGET_ARCH_VARIANT := armv7-a-neon
TARGET_ARCH_VARIANT_CPU := cortex-a15
TARGET_CPU_ABI := armeabi-v7a
TARGET_CPU_ABI2 := armeabi
TARGET_CPU_VARIANT := cortex-a15
# Kernel
BOARD_KERNEL_BASE := 0x10000000
BOARD_KERNEL_PAGESIZE := 2048
TARGET_KERNEL_CONFIG := i9500_defconfig

6. Create a vendorsetup.sh file to add your product (a “lunch combo”) to the build along with a build variant separated by a dash.
Here is the snapshot of vendorsetup.sh file

add_lunch_combo i9500-userdebug
add_lunch_combo i9500-eng
add_lunch_combo i9500-user

7. Proprietary device files should be copied from the device to the AOSP folder, the list of the files is specified here:

Including the kernel sources for the device

We can either use a pre-built kernel image or build the kernel from scratch, which can be configured by using BoardConfig.mk file under /device/vendor-name/device-name directory
Defining kernel source location:
TARGET_KERNEL_SOURCE := kernel/vendor-name/source-name
Configuring the device to build the kernel
TARGET_KERNEL_CONFIG := device-name_defconfig
If the device requires U-Boot we need to add the following in BoardConfig.mk file.
BOARD_USES_UBOOT := true
If we wish to use a pre-built kernel image, we need to need to add the following in BoardConfig.mk file.
TARGET_PREBUILT_KERNEL := device/vendor-name/device-name/kernel
Here is the snapshot of the BoardConfig.mk file

LOCAL_PATH := device/samsung/i9500
BOARD_VENDOR := samsung
# Include path
TARGET_SPECIFIC_HEADER_PATH := $(LOCAL_PATH)/include
# Assert
TARGET_OTA_ASSERT_DEVICE := ja3g,i9500,GT-I9500
# Bootloader
TARGET_BOOTLOADER_BOARD_NAME := universal5410
TARGET_NO_BOOTLOADER := false
# Platform
TARGET_BOARD_PLATFORM := exynos5
TARGET_SOC := exynos5410
# Architecture
TARGET_ARCH := arm
TARGET_ARCH_VARIANT := armv7-a-neon
TARGET_ARCH_VARIANT_CPU := cortex-a15

Building the custom ROM image and resolving the build issues

Android AOSP provides most of the toolchains for building the Android image. In addition to the toolchains available in the AOSP source, we need additional build packages for building the Android image, which are described in the link mentioned above in the prerequisites section.

  1. For building the Android image, following are the steps involved.
    Setting up the build environment. (need to be at the root of android source tree)
    source build/envsetup.sh
  2. Setting up device specific configuration
    lunch <device-name>
  3. Build the ROM image
    make -j4

General errors while building the android image are
Wrong JAVA version
For resolving we need to install the correct version of JAVA as mentioned for the android version.
– Missing files errors
Adding Kernel/feature in the config file and forgetting to add the sources. The solution is to find the missing file and supply it.
– Linking error
We may get some issues when we miss adding the dependencies. The solution is to include the dependencies in the modules’ makefile.
– Code errors
We can get these issues when there are any syntax errors in the code. The problem might be in a Java (.java) file, or in a C (.c) file, or in a C++ (.cpp) file or a header      (.h) or build config files. The solution is to correct the syntax errors.

Boot to recovery image and flashing the custom ROM

After successfully building the ROM image for the device, next step is flashing the ROM image on the device. For flashing the image on the device, the device needs to boot in recovery mode. The following commands are used for flashing the ROM image on the device.
For putting the device in recovery mode:
adb reboot bootloader
For Flashing the ROM image on the device:
      fastboot flashall -w

Debugging the boot up issues

Sometimes we face issues while booting the device after flashing the images. Following are some of the issues seen.

  1. Bootloop issue
  2. Display blank issue
  3. Camera not working
  4. Radio layer not working

For debugging these issues android provides some debug tools, which will enable us to debug and fix the issue. Following are the tools available for debugging purpose.

  1. ADB (Android Debug Bridge)
  2. GDB / KDB
  3. FASTBOOT tools
  4. Printk for kernel debug

Summary

This article provided a high-level overview on porting custom rom to an Android device. This guide discussed the process of porting the latest android release to existing android devices and the tools used for debugging the build and boot up issues.
Major tasks:

  1. Modifying Android native framework interfaces to fix issues related to specific features on surface flinger (Display blank out issue)
  2. Fixing kernel issues while building
  3. Application development
  4. Porting Lollipop and Marshmallow on device which had Kit-Kat installed.

Leave a Reply

At MSys Technologies, we are constantly seeking to expand our horizons by embracing modern technologies. We are a global technology services company with Storage, IoT, Cloud Computing, and Analytics. Download our brochure to learn more.