Best Practices of Porting Android OS to Embedded Platforms
February 16, 2021
Android is the popular smartphone operating system and it is taking over the tablet, automotive, smart TV, wearables, home appliances, gaming console market, and more. It offers distinct yet familiar experiences for embedded platforms, ranging from the smallest smartwatch screens to larger displays on foldable and chromebooks, to in-car entertainment systems, and up to the largest television screens. Android OS powered medical devices are also widely accepted in the healthcare industry. Thus, the porting of Android OS to the embedded platforms has recently garnered a lot of attention.
However, before executing Android OS porting, follow the below-mentioned practices to ensure efficient and successful Android porting.
Follow the Linux Kernel Coding Standard and Android Coding Standard
There are various procedures that are considered essential attributes of software development. These procedures are used for a particular programming language, programming style, methods, etc. A coding standard ensures that developers follow the specific guidelines to work on the project. It is necessary to follow Linux/Android coding standards while doing driver customization for Android porting. This ensures bug-free and easily maintainable drivers. It is also necessary to check that the code is free from unused variables.
Maintaining consistency while coding is crucial for the quality of the program. Also, follow the guidelines universally across different levels of the system to avoid contradiction with each other. The finished program code should be managed by or look like it was written by a single developer, in a single session.
Develop a Secure Boot and Image Authentication
The secure boot is the building block for the security architecture of the device. Technically, a secure boot is a boot sequence where each software image is loaded and executed on a device. Furthermore, this software image is authorized using a software. This sequence is designed to prevent running of unauthorized or modified code by checking all code before execution.
All the images loading follows the same general process called "loader." The loader allocates a safe area of memory to load the "The ELF Header," "The Program Header," and "The hash segment". The loader validates the hash segment by checking the image metadata, root certificate, certificate chain, and hash table. The loader verifies the loaded ELF segments by hashing them and comparing the hash value with the equal entry in the hash table. If there is a difference in any of the computed hash values, the image is rejected.
This process ensures that the loader will never accidentally overwrite important data in memory (including the loader’s code and data) with image data being loaded from untrusted storage.
Develop a Verified Boot
Verified Boot ensures all executed code comes from a trusted source (usually device OEMs). It creates a fullchain of trust right from a boot partition, a hardware-protected root of trust, and the bootloader to the other verified partitions including the system, vendor, and optionally OEM partitions. During device boot up, each stage verifies the integrity and authenticity of the next stage before handing over execution.
After that, Verified Boot checks for the correct version of Android with rollback protection because rollback protection helps to prevent a possible exploit from becoming persistent by ensuring that devices only updates to newer versions of Android. In addition, verified boot also allows Android devices to communicate their state of integrity with the user.
Port Linux Kernel for Android:
Android OS Porting
Porting the Linux kernel is one of the most important factors in porting Android. Download the appropriate Linux Version from kernel.org and port the Linux to your target board. This kernel is called as a Reference Kernel for your target board. Find an Android kernel that has the same revision as Reference kernel or else use the closest revision to simplify the procedure. Merge the Reference kernel and the Android kernel to a merged kernel which will be ported to the target board. A few new components integrated into the Linux kernel for Android are Debugger, AshMem, Open Binder, Power Manager, Low memory killer, and logger.
To configure the Merged kernel correctly for Android, you must test the known working configuration with a Linux root filesystem by building a kernel image from the merged source.
Note: Revision mismatch of the reference kernel and Android kernel will probably result in spending more time merging and debugging.
Ability to Configure the Upgrade (i.e. OTA) Server
OTA (Over-the-Air) is the mechanism used by Android for system-level updates in an Android device, like OS updates. It is recommended to insist the porting company use the Android OTA upgrade mechanism, rather than a home-grown upgrade system. Next, you can configure the OTA upgrade server to a server of your choice. This will give you control over the update process and control of when bug fixes are available to your customer. It also gives consistent user experience with Android consumer devices.
Things to consider while porting Android 11
Android 11 consists of various changes related to partitions layout that can support dynamic partitions - a userspace partitioning system for Android that enables creating, resizing, or destroying partitions during over-the-air (OTA) updates. These dynamic partitions take away the pain of vendors of managing individual sizes of partitions such as system, vendor, and product. Instead, the device allocates a super partition, and sub-partitions that can be sized dynamically within it.
When all vendor-specific information is factored out of the boot partition and relocated into a vendor-boot partition, it enables easy booting of an arbitrary device with GKI (Generic Kernel Image). Now the vendor boot partition contains information (such as flash page size, kernel, ramdisk load addresses, the DTB itself) that was previously contained in the boot partition. To successfully complete booting while porting Android 11, the bootloader must have access to both the boot and vendor boot partitions for enough data.
On a recovery image for non-A/B devices, the recovery image should contain information from a device tree blob (DTB) or Advanced Configuration and Power Interface (ACPI) overlay image. When such devices boot into recovery, the bootloader can then load the overlay image that is compatible with the recovery image. Devices that support A/B (seamless) updates should use recovery as boot instead of a separate recovery partition and Generic Kernel Image (GKI) must use a primary boot header version of 3 to be compatible with the vendor boot partition.
Following the above mentioned practices in embedded engineering, you can ensure efficient and successful Android porting on embedded platforms and enhance the capabilities of existing connected devices or design a new system from scratch, without too many hassles.
Kailas Kharse is associated with VOLANSYS Technologies as Senior Engineer. He has 7+ years of experience working on different Linux, Android, and KaiOS based projects, which include boot time optimization, Recovery Implementations, eMBMS implementation on feature phones, and more. He also has experience working on different SoCs from different manufacturers such as Qualcomm, TI, NXP, and Xilinx.