Android is the most popular operating system in the world, rolled out on billions of devices. What is the level of flexibility allowed across across the platform allowing third-party distributions of Android to exist?
On a lot of Android devices, boot loader security can be disabled. This is essential to be able to load third-party system software.
However, on some devices (and carriers), this is not the case. Those devices should be avoided if you plan on running third-party OSes.
On Android devices, a notice on each boot is displayed when running with third-party system software. Changing Secure Boot state involves a full data wipe.
Some devices also allow using AVB custom keys, to allow having both a locked bootloader and custom OSes, retaining the security infrastructure.
Partition layouts and kernel image format
The partition names are standardised across the ecosystem. The kernel image format is, too. Newer devices can have dynamic partitioning for even more flexibility.
On Qualcomm devices, the Android boot application is running under a UEFI TianoCore-based environment.
Android has a standard (re)flashing infrastructure implemented across the ecosystem, called fastboot. This allows installation instructions for custom operating systems to be identical across a wide variety of devices.
For devices shipping with Android 11 and kernel version 5.4, compatibility with the Generic Kernel Image is mandatory and is part of the certification process. However, the manufacturer can still choose to ship their own product kernel in that scenario.
Since devices first shipped with Android 12 and kernel version 5.10 or later, the kernel images used on-device are always Google-certified Generic Kernel Images.
Those branches as such have a stable kernel module ABI, allowing as such to update the kernel independently from the kernel-mode drivers.
Generic System Image
With devices shipping with Android 9 or later, a Generic System Image containing Android is guaranteed to run.
The drivers are in separate partitions with a stable ABI being guaranteed between Android and those vendor partitions.
Updates for 3rd-party system software
Vendor partitions are device dependent and aren’t distributed through a standard update infrastructure.
This means that if you use a third-party system software distribution with Generic System Images, you’ll have to handle driver updates (both kernel and user-mode) yourself to maintain product security guarantees.
However, even using an old driver set, you’ll still be able to run more recent releases of Android.
Halium is a project that aims to have non-Android Linux distributions working on modern Android devices.
For that project, a custom kernel build is currently used to enable kernel features that Android doesn’t use. Apart from that, the OS is identical across the whole set of devices.
However, Halium currently uses an Android 11 base. As such, it doesn’t have compatibility with devices launched with Android 12 yet.
In the future, a Generic Kernel Image + Generic System Image combination will allow to have non-Android Linux distributions that function without any device specific work on a wide variety of devices.
A lot of MediaTek devices shipping with Android ship with hypervisor support usable by Linux.
For Google Tensor, this support isn’t present in the currently shipped software. It’s however part of the Android 13 Developer Preview.
For Qualcomm devices, QHEE, Qualcomm’s own hypervisor, is currently present. This means that virtualisation isn’t currently accessible by Linux on those devices.
Non-Linux based operating systems (or mainline Linux without Android driver use)
If you can, go the virtualisation route. If you cannot, then device specific images will have to be used. You’ll have to provide your own driver sets instead of being able to use the vendor partitions present on the device.
A flattened device tree is given by the bootloader to describe devices on the platform. To boot an operating system using ACPI, shipping ACPI tables is needed.
To boot Windows, you can wrap a UEFI firmware to make it loadable as an OS kernel from the perspective of the Android boot application.