Android Common Kernel(ACK)
Android Kernel基于Linux Long Term Supported(LTS) kernel,并在此基础上添加了很多Android定制的Patch,形成了Android Common Kernels(ACKs)。
5.10及以上版本的ACK也被称为Generic kernel images(GKI) kernel。
GKI内核聚合了硬件无关的通用核心代码以及GKI模块,与Vendor模块分隔开来。
GKI为Vendor模块提供的接口,借助Kernel Module Interface(KMI)完成,KMI包含了一系列Vendor模块所需的函数和全局数据符号组成。

KMI的作用
ABI工具:https://android.googlesource.com/kernel/build/+/refs/heads/main-kernel/abi/
一直以来,Linux Kernel对主线内核维护一套稳定内核ABI的想法不屑一顾,因为面临不同的工具链、内核配置和快速发展的Linux主线内核,要在主线中保持稳定的ABI是非常困难的。
而Google为了解决Kernel碎片化引起的兼容性与安全性问题,就必须在GKI的基础之上,提供一个稳定的KMI给芯片、供应商(Vendor)开发自己的内核模块,提供独有的系统能力。
注意:KMI是ABI的一个子集,KMI定义的符号,用于Vendor内核模块的开发。此外ABI符号列表最终被编译到二进制stg中,KMI符号以文本形式放到文件中。
Google通过以下方式来提供稳定的KMI:
- 内核使用通用的Config(gki_defconfig)来进行GKI内核构建,这样核心内核函数以及全局数据结构的符号数量将会固定下来。
- KMI仅在同一LTS内核版本以及同一Android版本保持稳定。一旦Android版本或LTS内核版本有一个发生变化,都不保证KMI稳定性。
- AOSP自身提供特定版本的Clang工具链用于构建内核和内核模块。
- 强制Vendor模块必须使用KMI符号列表中的符号开发内核模块,如果发现使用非KMI符号,将会在运行时加载失败。
- 一旦KMI分支冻结,修改内核时无法再修改KMI符号列表中的符号定义,一旦改变将构建失败,并进行提示。
如何扩展KMI符号
https://source.android.com/docs/core/architecture/kernel/howto-symbol-lists
- 修改GKI内核功能
- 在KMI冻结之前,可以修改内核函数、数据结构,并通过Update the reference ABI representation流程更新ABI和KMI符号列表。修改需要提交给ACK,审批通过后生效。
- 在KMI冻结之后,依旧可以修改内核函数、数据结构,但是不能影响之前冻结的ABI。修改需要提交给ACK,审批通过后生效。
- 在GKI添加桩函数。修改需要提交给ACK,审批通过后生效。
- 在KMI增加已有的符号。修改需要提交给ACK,审批通过后生效。
如何确保Vendor模块和KMI、GKI兼容
使用目标ACK代码来开发内核或模块,将内核、ABI、KMI改动同步到ACK,并将开发完成的代码迁移回Byte的代码库。(如果项目Vendor部分已经和ACK进行或者有计划进行同步,可以直接用项目Vendor代码开发内核模块和内核功能)