Why Mainline Linux Cannot Boot an Android Phone
If Android is based on Linux, you might wonder why you cannot just compile the latest kernel from kernel.org and run it on a Pixel. Attempting to flash a raw upstream kernel image onto a Snapdragon device results in a dead phone. The CPU might spin up, but the screen stays black. The cellular radio remains silent, and the touchscreen ignores your inputs completely.
The problem lies in hardware discoverability. A PC motherboard acts like a standard USB port with built-in protocols like PCIe that allow the operating system to ask the hardware what is attached. Mobile hardware completely lacks this standardization. A System-on-Chip (SoC) operates more like a custom wiring harness. Every single pin's purpose must be manually documented before the engine will start.
The Linux kernel has no built-in way to query a mobile processor. Device makers must write a massive instruction manual called a Device Tree Blob (DTB) to map the physical hardware for the operating system. They also have to inject hundreds of custom out-of-tree drivers directly into the kernel source code just to make the display turn on.
Common Mistake: Beginners often assume "Linux is Linux" and that all hardware drivers are universally merged into the upstream kernel source. Mobile hardware moves too fast for standardized inclusion.
Because device makers had to manually inject custom drivers just to make basic hardware respond, a massive unmanageable chain of kernel forks was born.
The Million-Fork Problem and the ACK
Every time a new phone was built, the manufacturer had to create a custom version of Linux. This created a brutal hierarchy of code isolation. The journey of the kernel source code starts at Mainline Linux on kernel.org. That code eventually solidifies into a Long Term Support (LTS) release.
Google takes that LTS release and adds Android-specific power management and networking patches to create the Android Common Kernel (ACK). The fragmentation really accelerates after Google releases this baseline. Qualcomm takes the ACK and adds chip-specific drivers for their new Snapdragon processor. Samsung then takes Qualcomm's fork and adds specific drivers for the camera and display hardware on their new Galaxy device.
We can map out exactly how code flows down this chain, making it clear why security updates historically got trapped.
A critical security patch from kernel.org hits the LTS branch and gets pulled into the ACK. That patch often stalls in the ACK because the SoC vendor moved on to a newer chip and stopped rebasing their specific fork. The OEM cannot pull the security update without breaking their heavily customized hardware drivers.
This massive chain of forks made updating the kernel on older devices mathematically impossible. Google needed to introduce a hard boundary to fix the update cycle.
Splitting the Core: The Generic Kernel Image (GKI)
Updating the kernel previously required the SoC vendor to recompile everything from scratch. If Qualcomm dropped support for a three-year-old chip, the phone was permanently stranded on an old kernel. Google solved this by modularizing the kernel architecture.
They split the monolithic kernel binary in half. Core Linux and Android logic stay in one standardized box called the Generic Kernel Image (GKI). Hardware-specific drivers move into a separate box as Vendor Loadable Kernel Modules (LKMs). Think of the GKI as a sealed standardized engine block. The LKMs act as aftermarket custom parts bolted onto it.
As long as the mounting holes do not change, you can swap the engine block without throwing away the custom parts. Those mounting holes are the Kernel Module Interface (KMI). This architectural division allows the system to load standard code from one partition and device-specific code from another.
You can now flash a new LTS kernel security update onto a Pixel device by simply overwriting the /boot partition. The device reboots, dynamically loads the untouched Qualcomm LKMs from the /vendor_boot partition, and functions perfectly. The core system updates without touching the fragile hardware drivers.
Warning: Do not assume GKI means there is only one single kernel binary for all Android phones globally. The GKI is built per-architecture and per-LTS release.
Isolating vendor drivers into modules was a massive leap forward. Google wants to go further than just modularity. They want to eliminate the Android fork entirely.
Closing the Gap: The Push Upstream
Maintaining a massive custom patchset is exhausting. Every time kernel.org releases an update, Google engineers have to spend thousands of hours resolving merge conflicts in the ACK. The solution to this maintenance burden is upstreaming.
Upstreaming means pushing Android-specific code directly into the official Linux kernel tree. The goal is to shrink the ACK until the differences between Android and Mainline Linux disappear. Historically, features like wakelocks and binder were massive Android-only patches. Over the years, Google reworked these systems to meet the strict standards of the Linux kernel community.
Consider the Android Ashmem driver. Ashmem existed in the ACK for years as pure technical debt. Google eventually replaced it with memfd, a standard Linux mainline feature. This swap allowed them to delete thousands of lines of custom kernel code.
Interview Note: Mainlining mostly applies to the core Android framework requirements. SoC vendors will likely keep their LKMs closed-source, so do not expect fully open-source camera drivers anytime soon.
We started with a hardware crisis where mobile SoCs forced manufacturers to inject custom drivers directly into the Linux source code. Google solved this by establishing the GKI, splitting the core kernel from vendor-specific loadable modules. Now the focus is entirely on upstreaming Android features to reduce technical debt and align with mainline Linux.
Our hardware foundation is set. The components are awake and communicating through standardized interfaces. True user experience relies on a completely different environment. Next, we will cross the rigid boundary between Kernel Space and User Space to see how Android actually boots.