我的NPI项目之设备系统启动(八) -- Android14的GKI2.0开发步骤和注意事项
GKI是什么? Google为什么要推行GKI?
GKI全称General Kernel Image。GKI在framework和kernel之间提供了标准接口,使得android OS能够轻松适配/维护/兼容不同的设备和linux kernel。
Google引入GKI的目的是将Framework和Kernel进一步的解耦。因为,android一直高度依赖linux kernel, linux kernel一更新,android系统就要跟着适配更新。google发步的安全patch,也会因为kernel的版本而掣肘。
通用内核映像 (GKI) 项目通过统一核心内核并将 SoC 和板级支持从核心内核移至可加载模块中,解决了内核碎片化问题。GKI 内核为内核模块提供了稳定的内核模块接口 (KMI),因此模块和内核可以独立进行更新。
内核碎片化带来的问题:(市面上的内核版本太多,严重阻碍了Android的迭代更新),具体描述如下:
1. 安全更新需要耗费大量人力
Android 安全公告 (ASB) 中引用的安全补丁程序必须向后移植(旧的android 系统)到每个设备内核中。但是,由于存在内核碎片化问题,向正常使用的 Android 设备传播安全修复的代价非常之高。
2. 很难合并长期支持的更新
长期支持 (LTS) 版本包含安全修复和其他重大问题修复。事实证明,使用最新的 LTS 版本是提供安全修复的最有效方式。我们发现,ASB 报告的内核安全问题中有 90% 都已在保持最新状态的 Pixel 设备上得到修复。(简单一句话,打补丁不如升级OS)
不过,由于设备内核中所有的自定义修改,很难仅将 LTS 修复合并到设备内核中。
3. 妨碍 Android 平台进行版本升级
由于碎片化问题,很难向正常使用的设备添加需要更改内核的 Android 新功能。Android 框架代码必须假设支持的内核版本多达 5 个,并且没有针对新的平台版本进行任何内核更改(Android 10 支持内核版本 3.18、4.4、4.9、4.14 和 4.19;在某些情况下,这些版本自 2017 年 Android 8 发布以来还未添加新功能)。
4. 很难将内核更改贡献回上游 Linux
对内核进行完所有更改后,大多数旗舰设备附带的内核版本已经至少存在 18 个月了。例如,kernel.org 于 2017 年 11 月发布了 4.14 版内核,而首批使用 4.14 版内核的 Android 手机于 2019 年春季才发布(新特性上推linux main branch就太晚了)。
上游内核发布与产品发布之间的这种长时间延迟导致 Android 社区很难将所需的功能和驱动程序馈送到上游内核中,因此解决碎片化问题并非易事。
于是就有了GKI项目!!!!!大家还记得从Android8引入的Trible 机制吗?也是Android将framwork和linux kernel解耦的一个项目。
总而言之,无论是Android还是Apple OS 都是希望能够将自己的最新OS推送到尽可能多的设备上,从而抢占市场分额!
核心特性和目标如下:
1. 基于 ACK 来源构建而成。(ACK , Android/Aosp common kernel,Android最上游代码)
2. 是每个架构和每个 LTS 版本的单内核二进制文件以及关联的可加载模块(目前只有适用于 android11-5.4 和 android12-5.4 的 arm64)。
3.已经过关联 ACK 支持的所有 Android 平台版本的测试。在 GKI 内核版本的生命周期内不会发生功能弃用。
4. 为给定 LTS 中的驱动程序提供了稳定版 KMI。
5. 不包含 SoC 专用代码或板卡专用代码。(这个很好理解,不包含e.g specifc Qualcomm and Board code)。
Key features and goals of Android GKI include:
Stability(稳定性): The GKI aims to maintain a stable ABI(Application Binary Interface//应用程序二进制接口), ensuring that the Android framework can work with different kernel versions without requiring modifications.
Compatibility(兼容性): GKI enables Android to run on a wide range of devices with different kernel configurations, reducing fragmentation and enabling faster updates.
Portability(可移植性): By abstracting Android from the underlying kernel, GKI simplifies the process of porting Android to new devices and adapting it to different kernel versions.
Security(安全性): GKI facilitates the timely delivery of security patches(通常是Google的安全性补丁) and updates by decoupling the Android framework from the kernel, allowing for more efficient patching processes.
GKI可以更改吗?
通常在开发中我们不修改,而且其GKI镜像中的内容配置文件,我们也不可以修改,例如:
../kernel_platform/msm-kernel/arch/arm64/configs/gki_defconfig
但是Android的官网也提供了修改的方法,如下说明,分别有三个方面(再次提醒,通常作为ODM是不改的,(Android(ACK) / Qualcomm(供应商内核) / ODM(设备内核));
1. 将新功能配置为 GKI 模块。
2. 将内置内核功能配置为 GKI 模块。
3. 将受保护的 GKI 模块转换为不受保护的模块。
以上三个类型的修改,后面需要的时候可以进一步细看。有一个提醒就是,无论哪个修改,都必需需要提交更改以供审核。GKI 模块是 Android 专用内核功能,因此无需在上游提交模块转换补丁。不过,您必须按照其他准则提交 Android 通用内核 (ACK) 补丁。
什么是ACK,简称AOSP Common Kernel,应该是和LKML几乎一样的分支内容。官网的解释是
AOSP 通用内核(也称为 Android 通用内核或ACK https://android.googlesource.com/kernel/common/ )是kernel.org内核的下游,包含 Android 社区感兴趣的尚未合并到主线或长期支持 (LTS) 内核中的补丁。
官网对android-mainlin做简单介绍:
android-mainline是 Android 功能的主要开发分支。每当 Linus Torvalds 发布版本或候选版本时,Linux 主线就会合并到android-mainline中。 2019 年之前,Android 通用内核是通过克隆最近声明的 LTS(Long Time Support) 内核并添加 Android 特定补丁来构建的。这个过程在 2019 年发生了变化,从android-mainline分支出新的 Android 通用内核。这种新模型通过逐步实现相同的结果,避免了转发端口和测试 Android 补丁的大量工作。 android-mainline经过重要的持续测试,该模型从发布之日起就确保了高质量的内核。
当上游声明一个新的 LTS 时,相应的公共内核将从android-mainline分支出来。这允许合作伙伴在声明 LTS 版本之前通过从android-mainline合并来开始项目。创建新的通用内核分支后,合作伙伴可以无缝地将合并源更改为新分支。
其他常见的内核分支从其关联的LTS 内核接收定期合并。这些合并通常在 LTS 版本发布后立即完成。例如,当 Linux 4.19.64 发布时,它被合并到 4.19 通用内核中(例如android-4.19-q )。强烈鼓励合作伙伴(Qualcomm ? MTK?) 定期将通用内核(GKI)合并到其产品内核中,以及时了解 LTS 和 Android 特定错误修复的最新情况(Qualcomm 会不定期的去合并Android的通用内核补丁)。
所以,想给ACK 提交补丁一定是要经过严格省查的。所以,作为ODM开发中,通常不会这么做。对处理器/个别电子器件精通的内核维护者通常能够给linux内核提交patch,那也绝对是行业大牛;通常ODM开发内核中的驱动,我们通常需要定义在自己的config文件中,并且是一=m的形式进行编译。开机过程中,需要进行动态加载的。这个是目前GKI2.0的基本要求。
官网对GKI KMI内核分支介绍
GKI 内核具有稳定的内核模块接口。 KMI (内核模块接口)由内核版本和 Android 平台版本唯一标识,因此分支被命名为<androidRelease>-<kernel version> 。例如,Android 11 的 5.4 GKI 内核名为android11-5.4.对于 Android 12,还有两个额外的 GKI 内核: android12-5.4和android12-5.10 。kernel_platform/msm-kernel/Makefile. 我的高通平台是从Android 12 launch的。

也就是说,Android发布时候会绑定对应的linux kernel版本,目的是提供一个固定KMI。后续开发者可以根据KMI中的接口,进行对应的内核开发。

从 Android 12 开始,功能内核将少于启动内核,以限制功能内核的数量必须支持的稳定 KMI。
简单看下KMI的时间线:

每个 ACK KMI 分支都会循环经历三个阶段: 例如android12-5.10
开发阶段:
创建后,ACK KMI (我理解这是一个kernel分支,GKI则是对应的内核镜像)分支进入开发阶段(图 2 中的dev ),并开放为下一个 Android 平台版本提供功能贡献。当 5.10 被声明为新的上游 LTS 内核时,创建了android12-5.10 。内核版本的第二个 ACK KMI 分支可能会提前创建,以允许后续版本的开发。android13-5.10是在android12-5.10过渡出开发阶段时创建的。
稳定阶段:
当 ACK KMI 分支声明功能完成时,它会进入稳定阶段,在图 2 中标记为稳定阶段。合作伙伴功能和错误修复仍然被接受(合作伙伴:e.g Qualcomm),但启用了 KMI 跟踪以检测影响接口的任何更改。在此阶段,会接受破坏 KMI 的更改,但必须根据需要更新 KMI 定义。有关 KMI 监控的详细信息,请参阅GKI 概述。
冷冻阶段:
在将新平台版本推送到 AOSP 之前,ACK KMI 分支会被冻结,并在分支的生命周期内保持冻结状态。这意味着,除非发现严重的安全问题,且无法在不影响稳定 KMI 的情况下缓解,否则不会接受任何破坏 KMI 的更改。为了避免 KMI 损坏,如果 Android 设备不需要修复,则可能会修改或删除从 LTS 合并的一些补丁。
GKI1.0的情况,这里就不多解释,有个核心的要求是:GKI 1.0 不要求供应商模块可卸载,可以=y。
我们看看GKI2.0的情况下,
GKI 2.0 - GKI 产品
搭载 Android S (2021) 平台版本且使用内核版本 v5.x(5.x 是 2020 年年底被选为 LTS 的内核版本)或更高版本的设备必须附带 GKI 内核(将提供已签名的启动映像,并通过 LTS 和重大问题修复定期对其进行更新。由于 KMI 将保持二进制稳定性,因此无需对供应商映像进行任何更改,即可安装这些启动映像。
GKI 2.0 的目标
1. 不为 GKI 引入明显的性能或能效降低问题。
2. 使 OEM 无需供应商参与即可提供内核安全修复和问题修复 (LTS)。(是说OEM直接从Google 获取补丁?而不用从e.g Qualcomm获取?)
3. 降低更新设备主要内核版本(例如,将 v5.x 更新为 v5.y)所需的费用。(通常我们的升级直接从Qualcomm拉代码)
4. 通过按照清晰的升级过程更新内核版本,只为每个架构(例如Qualcomm6490 Armv7 架构)维护一个 GKI 内核二进制文件。
开发有关:
GKI2.0 下的内核开发,首先要注意,需要遵循GKI2.0中要求的ABI接口检查,目的是,你不能更改KMI中的接口。这个部分,可以在编译中进行检查。
详细的说明如下ABI检查如下:
ABI 工具使用 KMI 符号列表来限制必须监控哪些接口以实现稳定性。主符号列表包含 GKI 内核模块所需的符号。供应商应提交并更新其他符号列表,以确保其依赖的接口保持 ABI 兼容性。
符号列表包含报告的特定供应商或设备所需的符号。工具使用的完整列表是所有 KMI 符号列表文件的并集。ABI 工具会确定每个符号的详细信息,包括函数签名和嵌套数据结构。
当 KMI 被冻结时,不允许对现有 KMI 接口进行任何更改;它们是稳定的。
当有补丁改动了KMI 接口或者数据结构(例如include/linux/mmxx.h),应用此补丁后再次运行 build ABI 时,该工具会退出,同时显示非零错误代码并报告ABI错误。例如:
Leaf changes summary: 1 artifact changedChanged leaf types summary: 1 leaf type changedRemoved/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added functionRemoved/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable'struct mm_struct at mm_types.h:372:1' changed:type size changed from 6848 to 6912 (in bits)there are data member changes:[...]
最常见的错误原因是,驱动程序使用了内核中不在符号列表中的新符号。目前,我使用的符号表是:hon4490-android14-vendor/kernel_platform/common/android/abi_gki_aarch64_qcom,当出现问题时,第一时间检查该接口是否在符号列表中。
最后,新的设备驱动是需要单独配置到kernel configure中,而且必需以=m的形式进行,这是GKI2.0的标准要求。
举个例子:
例如,需要往内核中添加一个新的设备驱动,Touch的驱动。
1. 修改上一层目录中的Kconfig/Makefile,添加驱动编译规则,例如
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS) += xxx.o
那么,同样需要将CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS编译选项添加到整个内核的编译配置中,才能够在编译内核的时候进行编译。
这里使用到的就是 configs/vendor/xxx_GKI.config , 添加CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS=m的编译配置。其实同样可以添加到configs/vendor/xxx_consolidate.config。这里的区别是什么?原来,xxx_consolidate.config是编译userdebug时候被包含的配置文件。
那关于GKI2.0的大概历史就是这样,相关的开发注意事项需要结合开发过程进行深化理解。
实干出真知!
相关文章:
我的NPI项目之设备系统启动(八) -- Android14的GKI2.0开发步骤和注意事项
GKI是什么? Google为什么要推行GKI? GKI全称General Kernel Image。GKI在framework和kernel之间提供了标准接口,使得android OS能够轻松适配/维护/兼容不同的设备和linux kernel。 Google引入GKI的目的是将Framework和Kernel进一步的解耦。因…...
鼠标右键助手专业版 MouseBoost PRO for Mac v3.3.6中文破解
MouseBoost Pro mac版是一款简单实用的鼠标右键助手专业版,MouseBoost Pro for Mac只要轻点你的鼠标右键,就可以激活你想要的各种功能,让你的工作效率大幅度提高,非常好用。 软件下载:MouseBoost PRO for Mac v3.3.6中…...
React学习计划-react-hooks补充
React Hooks 1. 使用hooks理由 高阶组件为了复用,导致代码层级复杂生命周期的复杂 2. useState(保存组件状态) const [state, setstate] useState(initialState)3. useEffect(处理副作用)和useLayoutEffect(同步执行副作用) 使用方式: useEffect(…...
KTV点歌系统vue+springboot音乐歌曲播放器系统
目前现有的KTV点歌系统对于用户而言其在线点歌流程仍然过于繁琐,对于歌曲而言其系统安全性并不能保障。同时整套系统所使用的技术相对较为落后,界面不能动态化展示。相比较于其它同类型网站而言不能体现技术先进性。 1.2 项目目标 KTV点歌系统的后台开发…...
vue video 多个视频切换后视频不显示的解决方法
先说一下我这边的需求是视频需要轮播,一个人员有多个视频,左右轮播是轮播某个人员下的视频,上下切换是切换人员。 vue 代码 <el-carouselindicator-position"none"ref"carousel"arrow"always":interval&qu…...
多态与代码屎山
到底什么是多态呢?多态是面向未来的,比如企业采购为例: 一般分为线上合线下两种, 我们设计一个父类叫做"采购", 里面做一些共通的处理: 申请, 承认, 支付, 购买方式. 然后让各自的子类(线上,线下)实现自己的方法.实际调用过程中传入不同的对象就可以.到此为止项目开…...
Git基本操作(2)
Git基本操作(2) 上交文件之后,git文件的变化git cat-file HEAD指针里面有啥文件被修改git statusgit diff 文件名 版本回退(git reset)撤销回退git reflog 撤销的三种情况还没有addgit checkout -- [file] 已经add还没…...
编程笔记 Golang基础 023 切片
编程笔记 Golang基础 023 切片 一、切片二、定义与初始化三、基本操作四、示例 Go语言中的切片(slices)是基于数组的抽象数据类型,它提供了一种灵活的方式来处理可变长度的数据序列。切片本身不存储任何数据,而是指向底层数组的一…...
qt 软件发布(Windows)
1. 开发环境 QtCreator MSVC编译器 2. 源码编译 生成release或者debug版本的exe可执行文件(x64或x86) 3. windeployqt 打包 ①左下角开始菜单栏找到QT的命令交互对话框,如下图MSVC 2017 64-bit(根据第二步编译的类型选择64位或者32位)。 ②cd 切换到第二步可…...
《汇编语言》- 读书笔记 - 第11章-标志寄存器
《汇编语言》- 读书笔记 - 第11章-标志寄存器 标志寄存器指令与标志位关系11.1 ZF(Zero Flag,零标志位)11.2 PF(Parity Flag,奇偶标志位)11.3 SF(Sign Flag,符号标志位)处…...
1.QT简介(介绍、安装,项目创建等)
1. QT介绍 Qt(官方发音 [kju:t])是一个跨平台的C开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序 Qt 是纯 C 开发的,正常情况下需要先学习C语言、然后在学习C然后才能使用…...
【服务器】服务器推荐
一、引言 在数字世界的浪潮中,服务器作为数据存储和处理的基石,其重要性不言而喻。而在这个繁星点点的市场中,雨云以其独特的优势和超高的性价比,逐渐成为众多企业和个人的首选。今天,就让我带你走进雨云的世界&#…...
信号系统之线性图像处理
1 卷积 图像卷积的工作原理与一维卷积相同。例如,图像可以被视为脉冲的总和,即缩放和移位的delta函数。同样,线性系统的特征在于它们如何响应脉冲。也就是说,通过它们的脉冲响应。系统的输出图像等于输入图像与系统脉冲响应的卷积…...
uniapp腾讯地图JavaScript Api,H5端和原生APP端可用
因项目需要,在uniapp中集成使用腾讯地图,为了方便维护,希望通过一套代码实现H5和APP同时可用。H5显示相对简单,APP端比较麻烦,记录下实现过程 一、集成步骤 1.使用 renderjs script标签使用renderjs,因为…...
MyBatisPlus:PG数组类型自动映射问题
引言: PostGreSQL数据库提供了丰富的数据类型,通过查看官网文档,我们也可以发现,PG也提供了对数组类型的支持。 但是在实际开发中,我们通常是使用MyBatis/MyBatisPlus这种半自动ORM映射框架来实现数据库/表数据基本的增删改查,以及其它操作。那么,问题来了,如何…...
Data-Shape制作UI节点简介
很多小伙伴对于Data-Shape制作简单的UI都是似懂非懂,群里很多小伙伴也总是询问相关的问题,那么,今天我就简单举几个例子,专门介绍下Data-Shape创建简单UI的教程。 首先,本次教程,使用的是Data-Shape 2021.…...
kubernetes负载均衡部署
目录 1.新master节点的搭建 对master02进行初始化配置(192.168.88.31) 将master01的配置移植到master02 修改master02配置文件 2.负载均衡的部署 两台负载均衡器配置nginx 部署keepalived服务 所有node节点操作 总结 实验准备: k8s…...
NestJS入门6:日志中间件
前文参考: NestJS入门1 NestJS入门2:创建模块 NestJS入门3:不同请求方式前后端写法 NestJS入门4:MySQL typeorm 增删改查 NestJS入门5:加入Swagger 1. 安装 nest g middleware logger middleware 2. lo…...
CommonJS、require、moudle实现两个文件传参
目的:实现两个文件传参 文件A给B传入一个参数,并且文件B代码执行后再传回A。 场景 拆分express项目中的app.js文件中的路由、项目越大会使app.js文件变大,复杂 如何使用 app.js文件 导入路由文件调用路由文件,调用的时候传入…...
关于php、php-fpm的解释
PHP语言是由PHP程序解释的,而不是由php-fpm程序解释的。 PHP(Hypertext Preprocessor)是一种通用开源脚本语言,最初是为创建动态Web页面而设计的,但现在也可以用于命令行脚本编写等用途。PHP程序通常由Web服务器&…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
