Android GKI 架构 + GKI改造原则、机制和方法
Android GKI 架构简介
https://blog.csdn.net/shift_wwx/article/details/126347543
相关术语:
ACK:Android Common Kernel
AOSP:Android Open Source Project
GKI:Generic Kernel Image
KMI:Kernel Module Interface
LTS:Long Term Supported
DLKM:Dynamically loadable kernel module
GSI:Generic System Image
VTS:Vendor Test Suite
CTS:Compatibility Test Suite
图1 Android 内核层次结构导致碎片化问题
3. GKI
GKI 通过统一核心内核并将 SoC 和板级支持从核心内核移至可加载模块中,解决了内核碎片化问题。GKI 内核为内核模块提供了稳定的内核模块接口 (KMI),因此模块和内核可以独立进行更新。
GKI 有以下特点:
- GKI 从ACK sources 编译而来;
- GKI 是每个架构和每个 LTS 版本的single-kernel binary 加上关联的可加载模块。(目前只有适用于
android11-5.4
和android12-5.4
的 arm64); - GKI 已经过了关联 ACK 支持的所有 Android 平台版本的测试。在 GKI 内核版本的生命周期内不会发生功能弃用;
- GKI 为给定 LTS 中的驱动程序提供了稳定版 KMI;
- GKI 不包括SoC 专用代码或板卡专用代码;
图2 GKI kernel 和vendor模块 架构
更新点的ACKs 也称为 GKI kernels,因为它们支持分离硬件无关的通用核心内核代码和硬件无关的GKI 模块。GKI kernel 与特定于硬件的供应商模块交互,这些模块包含芯片上的系统和特定于板的代码。GKI kernel 和供应商模块之间的交互,是通过KMI 来实现的,该接口由标识供应商模块所需的函数和全局数据的符号列表组成。
GKI改造原则、机制和方法
https://blog.csdn.net/feelabclihu/article/details/113409593
Google在android11-5.4分支上开始要求所有下游厂商使用Generic Kernel Image(GKI),需要将SoC和device相关的代码从核心内核剥离到可加载模块中(下文称之为GKI改造),从而解决内核碎片化问题。GKI为内核模块提供了稳定的内核模块接口(KMI),模块和内核可以独立更新。本文主要介绍了在GKI改造过程中需遵循的原则、遇到的问题和解决方法。
一、不能破坏KMI
冻结KMI后,分支在其整个生命周期中都保持冻结状态,原则上不会接受破坏KMI的修改(除非发现严重的安全问题,且不能在不影响KMI稳定的情况下得到缓解)。在冻结的分支中,只有不破坏KMI的bug修复和partner features才能被接收。在不影响现有KMI接口的前提下,可以使用新导出的符号扩展KMI,新接口被接收添加到KMI后,必须保持稳定,不能被将来的修改破坏。
二、内核模块只能使用已export并添加到白名单中的接口
三、vendor hook机制
考虑到SoC和OEM厂商可能要对原生内核做一些客制化修改和优化,Google提供了一套vendor hook机制,下游厂商在需要修改内核源码的地方添加hook,并向Google申请,将patch upstream到AOSP。
推荐方法:
根据使用场景选择适合的vendor hook变量,在可能会调度的场景需要使用受限制的vendor hook
四、vendor hook延伸
SoC和OEM feature都要从内核剥离出来编译成内核模块,内核源码中相互调用export接口是没有问题的,那么模块之间相互调用export接口呢?
推荐方法:
借鉴Google的vendor hook机制,在A模块中定义并export全局变量,B模块初始化函数中将callback函数注册绑定到该全局变量,这样只有B模块调用A模块中的变量和接口,A模块通过hook变量回调B模块中接口,解决编译调用问题。
五、通过内核已有的事件注册接口替代vendor hook