GKI改造原则、机制和方法

2023-05-16

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后,必须保持稳定,不能被将来的修改破坏。

1. 问题现象:

替换google boot.img后,开机串口有如下打印错误,

[    1.669135] init: Loading module /lib/modules/foo.ko with args ""

[    1.676281] foo: disagrees about version of symbol xxx

 

2. 原因分析:

出现这种错误可能的原因是ko中调用的符号与vmlinux中的符号crc值不匹配,如在KMI接口使用的结构体中增加了新字段,间接地修改了接口定义:

 

3. 推荐方法:

(1) 扩展内核原生结构体和接口

(2) 向google申请,在内核原生结构体中加入一些padding

Google在android11-5.4分支中新增了两个宏

 

ANDROID_VENDOR_DATA,在结构体中保留一些padding以备将来可能的使用,这些padding正常的都是位于结构体尾部,padding变量标识n从1开始递增。

ANDROID_VENDOR_DATA_ARRAY同ANDROID_VENDOR_DATA,分配一个数组,数组大小是s,元素是u64类型。

下面是使用ANDROID_VENDOR_DATA和ANDROID_VENDOR_DATA_ARRAY在内核结构体中增加新字段的示例:

4. 措施:

在编译脚本中增加检测,编译GKI kernel后,比较生成的Module.symvers和原生android/abi_gki_aarch64.xml文件中符号的crc值,如果crc值不匹配,编译报错,表示使用了非规则的方法修改原生接口或结构体。

 

二、内核模块只能使用已export并添加到白名单中的接口

android11-5.4分支build.config.gki.aarch64文件中有如下配置

表示模块只能使用abi_gki_aarch64文件中的符号。

1. 问题现象:

替换google boot.img后,串口有如下打印错误:

[    1.735506] foo: Unknown symbol xxx(err -2)

 

2. 原因分析:

原生内核没有用EXPORT_SYMBOL_GPL把接口xxx export,或已经export的接口没有添加到白名单(该接口abi可能不稳定)

 

3. 推荐方法:

(1)  Google建议向上游linux社区申请将要使用的内核接口export,并向Google申请,将接口添加到白名单android/abi_gki_aarch64_xxx

(2)使用其他已在白名单中的接口替代。

 

三、vendor hook机制

考虑到SoC和OEM厂商可能要对原生内核做一些客制化修改和优化,Google提供了一套vendor hook机制,下游厂商在需要修改内核源码的地方添加hook,并向Google申请,将patch upstream到AOSP。

1. vendor hook实现步骤如下:

(1) 在include/trace/hooks/目录下创建一个新的头文件xxx.h,定义一组hook接口register_trace_android_vh_xxx、trace_android_vh_xxx和全局变量__tracepoint_android_vh_xxx

(2) 在drivers/android/vendor_hooks.c文件中包含hook头文件xxx.h,export hook变量__tracepoint_android_vh_xxx给模块使用

(3)在内核模块中增加register代码将回调函数绑定到hook变量__tracepoint_android_vh_xxx

(4) 在内核xxx.c文件中包含hook头文件xxx.h,调用hook接口trace_android_vh_xxx(即hook变量__tracepoint_android_vh_xxx绑定的callback函数)

2. 问题现象:

测试偶现dump “BUG: scheduling while atomic:”

 

3. 原因分析:

vendor hook变量有两种,都是基于tracepoints的:

正常的:使用DECLARE_HOOK宏创建tracepoint函数trace_<name>,要求name在trace中是独一无二的,callback函数的调用是在关抢占的场景中使用的

受限制的:受限制的hook在scheduler hook类的场景中使用,绑定的callback函数可以在cpu offline或非原子上下文中调用(调用前没有关抢占),受限制的vendor hook不能被解绑定,所以绑定的模块不能卸载,只允许有一个绑定(任何其他绑定将会返回-EBUSY错误)。

 

4. 推荐方法:

根据使用场景选择适合的vendor hook变量,在可能会调度的场景需要使用受限制的vendor hook

 

四、vendor hook延伸

SoC和OEM feature都要从内核剥离出来编译成内核模块,内核源码中相互调用export接口是没有问题的,那么模块之间相互调用export接口呢?

1. 问题现象:

编译报错 depmod: ERROR: Found 2 modules in dependency cycles!

 

2. 原因分析:

模块之间相互调用export接口,导致编译时报错。

3. 推荐方法:

借鉴Google的vendor hook机制,在A模块中定义并export全局变量,B模块初始化函数中将callback函数注册绑定到该全局变量,这样只有B模块调用A模块中的变量和接口,A模块通过hook变量回调B模块中接口,解决编译调用问题。

五、通过内核已有的事件注册接口替代vendor hook

是不是只能通过vendor hook实现修改内核呢?

android11-5.4分支log中有这么一笔关于vendor hook的提交:

为按键组合增加vendor hook

我们注意到内核中有一个接口input_register_handle,它的注释是注册一个新的input handle,添加到设备和handle列表中,只要使用input_open_device()接口打开设备,输入事件触发后会轮询到该handle,input_register_handle接口应该在handler的connect方法中调用,因此我们可以使用input_register_handler、input_register_handle来实现上述的按键组合功能,不需要在内核中增加vendor hook。

通过这个改造示例,启发我们思考是否只能使用vendor hook机制,是否可以使用其他内核已有的机制、事件注册接口将原先嵌入在内核中的feature剥离出来。

 

参考文章

[1]  https://source.android.com/devices/architecture/kernel/generic-kernel-image

[2]  https://blog.csdn.net/geshifei/article/details/94360470

[3]  https://blog.csdn.net/qq_39937242/article/details/82631165

长按关注

内核工匠微信

Linux 内核黑科技 | 技术文章 | 精选教程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GKI改造原则、机制和方法 的相关文章

  • 谨以此文献给才毕业一两年的朋友

    谨以此文献给才毕业一两年的朋友 选自同事信件 谨以此文献给才毕业一两年的朋友我们终于进入了这个社会 从此结束了被学校老师看管的生涯 xff0c 结束了做父母乖宝贝的日子 xff0c 也结束从父母兄长那里拿钱的幸福时光 我们从家里搬了出来 x
  • layui实际项目使用过程中遇到的兼容性问题

    layui实践兼容 本文记录自己在layui的实际使用过程中遇到的一些兼容性问题 xff0c 烂笔头 gt gt gt 大脑 layui在vue项目中不能自动渲染的问题 下载layui源码到本地 xff0c 在vue的项目中引用 xff0c
  • Vue从零开始01——Vue双向绑定原理和MVVM

    Vue是一个主张较弱的渐进式框架 xff0c 什么是主张弱的渐进式框架呢 xff1f 主张弱和渐进式说的都是 xff0c 可以灵活的选取你需要用的东西和不需要用的东西 xff0c 需要用的就引进来 xff0c 不需要用的就不引 xff0c
  • layui数据表格复选框自动选中部分选项

    layui数据表格复选框自动选中部分选项 layui官方文档中给出了数据表格复选框全选字段 xff0c 如下 xff0c 但是部分选中没有配置项 部分选中的方法 xff1a 利用异步数据接口的参数 xff1a 实现代码 xff1a layu
  • Js代码收藏大全

    1 nc ntextmenu 61 34 window event returnvalue 61 false 34 将彻底屏蔽鼠标右键 lt table border nc ntextmenu 61 return false gt lt t
  • jenkins(linux)远程构建windows项目(超详细)

    1 背景 公司开发的资产管理探针需要在linux unix windows上分别部署 xff0c 使用自动化构建jenkins工具远程部署linux平台容易实现 xff0c windows比较折腾 xff0c 现将个人经验分享 2 环境 I
  • jq实现点击一个按钮,触发另一个点击事件

    jq实现点击一个按钮 xff0c 触发另一个点击事件 span class token function span span class token punctuation span span class token string 34 a
  • Promise.race()异步超时处理

    span class token keyword function span span class token function timeoutPromise span span class token punctuation span p
  • Ztree点击树节点选中前面的复选框

    span class token keyword var span setting span class token operator 61 span span class token punctuation span check span
  • 关于vue-cli项目搭建完成之后的yarn serve启动指令

    在项目的配置文件package json里面 xff0c 声明了两条指令的快捷指令 xff0c 当执行yarn serve的时候就相当于执行了vue cli service serve这条指令
  • Vue项目url中的BASE_URL解析

    在Vue中遇到很多url都用到了 lt 61 BASE URL gt 这个东西 span class token operator lt span span class token operator 61 span span class t
  • VSCode 中 js 文件类型注释报错的问题解决

    在阅读 Vue js 源码的时候遇见的一个问题 xff0c 本来可以忽略的玩意 xff0c 但是报错的波浪线 xff0c 如鲠在喉实在受不了 xff0c 解决之 报错说明 Type annotations can only be used
  • 3-3-07-nuxtjs案例realworld-nuxtjs

    realworld nuxtjs 项目地址 xff1a https gitee com dingxd9702 realworld nuxtjs 创建项目 mkdir realworld nuxtjsyarn init yyarn add n
  • 3-4-01-搭建自己的 Server Side Render

    搭建自己的 Server Side Render Vue 实例的服务端渲染 使用 vue server renderer 插件完成 vue 实例的服务端渲染使用 express 创建一个 node 服务器fs 模块读取 html 模板 sp
  • css实现超出部分显示省略号

    显示一行 xff0c 省略号 white span class token operator span space span class token punctuation span nowrap span class token punc
  • 正则表达式 匹配字符串 matches()方法的运用

    package cn niit demo5zhengze 正则表达式 匹配字符串 matches 方法的运用 public class Test public static void main String args checkQQ che
  • Blazor组件自做三 : 使用JS隔离封装ZXing扫码

    本文基础步骤参考前两篇文章 Blazor组件自做一 使用JS隔离封装viewerjs库 Blazor组件自做二 使用JS隔离制作手写签名组件 1 在文件夹wwwroot lib 添加zxing子文件夹 里面下载库文件 文件文末源码里可复制
  • zabbix报警方式,邮件报警和微信报警。

    整理csdn时候发现了一篇2016年整理zabbix报警不知道当时啥情况没有发布出去 xff0c 凑个数重新发布 最近这些天都在弄Zabbix不再只是简单的监控物理硬件 xff0c 服务端口 xff0c 流量图等 让Zabbix的功能发挥到

随机推荐

  • itk registration 1

    参考 xff1a https itk org ITKSoftwareGuide html Book2 ITKSoftwareGuide Book2ch3 html x26 1740003 18 图像配准是确定将一幅图像上的点映射到另一幅图像
  • 凤凰涅槃

    涅槃 xff0c 涅槃 xff0c 太阳般灿烂 xff0c 黑色的凤凰飞入烈火 xff0c 一切腐朽烧干 涅槃 xff0c 涅槃 xff0c 大海般坦然 xff0c 红色的凤凰浴火重生 xff0c 一切希望复燃 涅槃 xff0c 涅槃 xf
  • Qt单个模块的编译

    有可能使用的Qt没有自己需要的模块 xff0c 这个时候就只能自己去编译这个模 本次就拿QWebEngine这个模块来讲 xff0c 这个模块比较复杂 xff0c 编译很容易出问题
  • H5/js/web lottie解析json 播放视频或动画

    H5 js web lottie解析json 播放视频或动画 1 需要UI设计的小伙伴用AE把效果图导出时导成JSON格式 xff0c 并且把json引入到你需要用到的项目里面2 在index html中引入lottie min js3 查
  • VirtualBox虚拟机闪退后如何重新打开

    电脑 xff08 Mac系统 xff09 由于某种问题自动重启了 xff0c 重启后之前在用的VirtualBox xff08 虚拟机管理器 xff09 能恢复运行 xff0c 但VirtualBoxVM xff08 虚拟机终端 xff09
  • (五)建筑物多边形化简系列——最小外接矩形的获取

    最小外接矩形问题是在给出一个多边形 xff08 或一群点 xff09 xff0c 求出面积最小且外接多边形的矩形的问题 这个问题看起来并不难 xff0c 但是具体实现并不简单 除了调用现有的公开库之外 xff0c 这里给出一种简单且易理解的
  • 使用 LxRunOffline 实现 WSL 自定义安装、备份

    本文初衷是想在非默认目录下安装WSL xff0c 查阅资料后用LxRunOffline了解并实现了WSL自定义安装 前言 虽说目前的 WSL 在 Windows 10 生态中已经越发成熟 xff0c 但在实际使用中依旧存在一些不足之处 xf
  • [Python基础] @statismethod和@classmethod中的注意事项

    声明 xff1a 以下讨论将区别方法 xff08 method xff09 和函数 xff08 function xff09 两个概念 xff0c 方法依托于对象 xff0c 而函数可以脱离对象之外存在 众所周知 xff0c python类
  • centos安装chrome 无法运行 Running as root without --no-sandbox is not supported ygote_host_impl_linux.cc

    launcher Failed to get the debug url 0313 145713 562233 ERROR zygote host impl linux cc 90 Running as root without no sa
  • Blazor组件自做七: 使用JS隔离制作定位/持续定位组件

    1 运行截图 演示地址 2 在文件夹wwwroot lib 添加geolocation子文件夹 添加geolocation js文件 本组件主要是调用浏览器两个API实现基于浏览器的定位功能 现代桌面和移动端都支持 包括MAUI Blazo
  • 普通表转换分区表操作步骤

    普通表转换分区表操作步骤 1 转分区表原因 生产数据库 xff0c 一张表 xff0c 一亿多行数据 xff0c 绝大部分查询按月为维度做时间范围查询 xff0c 未分区状态下 xff0c 查询IO量大 xff0c 计划以分区截剪的方式减少
  • 信号量的实现和应用

    信号量的实现和应用 一 实验环境 本次实验的操作环境还是一样的实验环境 环境文件如下 xff1a 如果不清楚的话请参考往期博客 二 实验目标与内容 1 目标 xff1a 加深对进程同步与互斥概念的认识 xff1b 掌握信号量的使用 xff0
  • Linux常用软件包(常用命令)

    文章目录 Linux应用程序基础RPM包管理工具rpm命令的格式查询RPM软件包信息应用程序与系统命令的关系软件包的封装类型rpm软件包查询未安装的 RPM 软件包文件中信息安装 升级 卸载 RPM 软件包yum常用的操作命令 编译安装编译
  • KBQA的工作流程(基于检索的方法)

    KBQA的工作流程 基于检索的方法 图谱构建阶段 注 采用neo4j的方法进行建立图数据库 1 数据准备 结构化数据 例如mysql的关系型数据库 进行整理 导出为csv 半结构化数据 采用包装器技术 进行抽取 之后 进行清洗 文本数据 采
  • 可解压rar、zip且可打包7z的powershell命令

    安装模块 Install Module 7zip4powershell 为什么要使用7zip 1个原因是传统zip只支持最大2gb的文件 xff0c 而7zip支持 16 xff0c 000 xff0c 000TB大的文档 xff0c 另一
  • ubuntu18.04 systemd配置学习手册(1) --相关概念

    1 从init系统说起 Linux 操作系统的启动首先从 BIOS 开始 xff0c 接下来进入 boot loader xff0c 由 bootloader 载入内核 xff0c 进行内核初始化 内核初始化的最后一步就是启动 PID 为
  • ubuntu18.04 systemd配置学习手册(2) --具体使用

    转载 xff1a http www ruanyifeng com blog 2016 03 systemd tutorial part two html 1 开机启动 对于那些支持 Systemd 的软件 xff0c 安装的时候 xff0c
  • 建造者模式(Builder模式)详解

    在软件开发过程中有时需要创建一个复杂的对象 xff0c 这个复杂对象通常由多个子部件按一定的步骤组合而成 例如 xff0c 计算机是由 OPU 主板 内存 硬盘 显卡 机箱 显示器 键盘 鼠标等部件组装而成的 xff0c 采购员不可能自己去
  • 关于读取文件失败

    太久没遇上这个问题了 今天碰上刚好回顾一下 文件路径以及python语法中涉及到的反斜杠 转义符问题 xff0c 在python字符串中 有转义的含义 xff0c 如 t可代表TAB xff0c n代表换行 xff0c 所以我们需要采取一些
  • GKI改造原则、机制和方法

    Google在android11 5 4分支上开始要求所有下游厂商使用Generic Kernel Image xff08 GKI xff09 xff0c 需要将SoC和device相关的代码从核心内核剥离到可加载模块中 xff08 下文称