Android的linux内核解耦
android设备内核部分,除android定制性修改外还有芯片供应商、ODM/OEM的修改,为了隔离他们的影响,做了内核解耦部分内容。
1、boot内容
查看Boot Image Header,version 2版本包含内容最多,包括了内核、设备树、根目录、recovery设备树,cmdline。boot拆包与内容解析参考1、Android bootimg kernel(boot.img)
2、linux的ramdisk解耦
2.1、ramdisk加载情况
2.1.1、android 13没有recovery分区
![](https://img-blog.csdnimg.cn/img_convert/bdf2cac48f330cc303964b6b51bc0f3a.png)
vendor_boot的ramdisk,init_boot 的ramdisk,boot镜像的GKI,system的tmpfs共同加载到RAM。根据命令参数选择正常Boot Android还是Boot recovery。
2.1.2、android 13 AB系统有recovery分区情况
![](https://img-blog.csdnimg.cn/img_convert/2a7d12cf147cd22b58dc46bd21f7e375.png)
Boot Android还是加载vendor_boot的ramdisk,init_boot 的ramdisk,boot镜像的GKI,system的tmpfs;
Boot recovery加载vendor_boot的ramdisk,init_boot 的ramdisk,boot镜像的GKI,system的tmpfs以及recovery ramdisk。
2.1.3、android 13 non-AB系统有recovery情况
![](https://img-blog.csdnimg.cn/img_convert/398034d0dd1f0db38aa291d5dc0baa52.png)
Boot Android还是加载vendor_boot的ramdisk,init_boot 的ramdisk,boot镜像的GKI,system的tmpfs;
Boot recovery加载recovery的GKI和ramdisk,boot镜像的GKI与tmpfs;
2.2、ramdisk加载解析
上面三张图来自android开发者社区,显然大家很难看懂,我们抓下面三个关键来看图:
1、init分了两个阶段,每个阶段使用不同的资源文件,Android和recovery模式均是两个阶段。
2、启动必然要kernel,这个kernel在哪个分区?
3、进入recovery的核心二进制文件/system/bin/recovery以及它的资源文件在哪个分区?
相关内容所在分区整理表格如下
android 13 无recovery分区 | android13 AB 有recovery分区 | android 13 non-AB 有recovery分区 | ||
android模式 | 1nd init | init_boot分区 | init_boot | init_boot |
1nd resource | vendor_boot&init_boot | init_boot | init_boot | |
2nd init | system | system | system | |
2nd resource | system | system | system | |
kernel | boot kernel | boot kernel | boot kernel | |
recovery模式 | 1nd init | init_boot分区 | recovery ramdisk | recovery ramdisk |
2nd init | init_boot | recovery ramdisk | recovery ramdisk | |
kernel | boot kernel | boot kernel | recovery kernel | |
recovery二进制执行文件 | vendor_boot | recovery ramdisk | recovery ramdisk | |
recovery resource | vendor_boot | recovery ramdisk | recovery ramdisk |
2.3、ramdisk加载总结
根据上表分析:
1、android模式加载流程基本相同,init第二阶段均需要是用system里面的ramdisk;
2、recovery模式,有recovery分区则1nd init、2nd init、recovery执行文件与资源文件从recovery加载、否则1nd init、2nd init从init_boot加载,recovery执行文件与资源文件从vendor_boot加载;
3、没有recovery分区情况和AB系统情况一直使用同一内核boot GKI,non-AB系统有recovery分区情况在recovery模式下使用recovery的GKI。
3、linux的Kernel解耦
![](https://img-blog.csdnimg.cn/img_convert/3e9d460e3bffa33b4039d088a53b2dd3.png)
上图就是android的kernel解耦情况。
generic Kernel是Linus Torvalds维护的linux宏内核、GKI Modules是android定制模块,合称GKI;GKI对外接口是KMI;Vendor Modules是动态加载模块,通过KMI与GKI通信。
但是目前动态加载模块加载与执行效率并不理想,andorid还在优化。
这章关键在理解linux的分支管理与动态加载模块,以及KMI接口。内容多引用官网。
3.1 GKI
android底层是linux,这个linux除Linus Torvalds维护的宏内核外还有下面三方的修改:
1、android system针对linux的定制性修改,例如低内存终止守护进程(一个内存管理系统,可更主动地保留内存)、唤醒锁定(一种 PowerManager 系统服务)、Binder IPC 驱动程序、启动验证用的设备映射dm-mapper、OTA升级用的设备映射快照dm-snapshot、文件系统加密用的fscrypt等等;
2、芯片厂商vendor添加的内核方案,包括电源管理/DVFS、系统基础支持、PCIe和USB等高速外围设备等等;
3、ODM/OEM也有自己内核的方案,例如各家的驱动、外设方案。
现在google要脱离芯片厂商与ODM/OEM影响,对linux进行解耦。
3.2 KMI
![](https://img-blog.csdnimg.cn/img_convert/1676d2d957aded1c7621ec8ecb6de2db.png)
3.3 GKI Modules与Vendor Modules
其实都是linux动态加载模块(不知道的自己查询),关键点在KMI的规范与稳定。
system的GKI模块,放置到system_dlkm里面,开机挂载分区安装,system_dlkm编译参考https://source.android.google.cn/docs/core/architecture/partitions/gki-partitions
将新功能配置为 GKI 模块
对于新功能,编辑gki_defconfig并将所需内核功能的配置项从n设置为m ( =m )。在arch/arm64/configs/gki_defconfig和arch/x86/configs/gki_defconfig中设置此设置。
将为该功能生成的 KO ( .ko ) 文件添加到common/modules.bzl的COMMON_GKI_MODULES_LIST部分。按排序顺序添加文件。如果您不确定生成的所有文件,构建将失败并列出要添加到列表中的所有必需的 KO 文件。
将步骤 2 中的同一组 KO 文件添加到common/android/gki_protected_modules以将模块指定为受保护的 GKI 模块,在运行时按升序排序以进行二进制搜索。指定为受保护 GKI 模块的模块仍必须经过 Google 批准才能成为官方受保护模块。
将步骤 2 中的同一组 KO 文件添加到common/android/gki_system_dlkm_modules ,以在运行时按升序排序以进行二进制搜索,以确保将文件复制到内核的out/<androidX-YZ>/dist/system_dlkm.img和out/ androidX-YZ /dist/system_dlkm_staging_archive.tar.gz 。 system_dlkm_staging_archive.tar.gz存档中的模块可用作输入以在平台构建中生成system_dlkm.img 。
提交您的更改以供审核。 GKI 模块是 Android 独有的内核功能,因此不需要向上游提交模块转换补丁。但是,您必须遵循其他准则来提交 Android 通用内核 (ACK) 补丁。
vendor添加动态加载模块官网地址
https://source.android.google.cn/docs/core/architecture/partitions/vendor-odm-dlkm-partition
添加vendor动态加载模块规则
https://source.android.google.cn/docs/core/architecture/kernel/vendor-module-guidelines
4、dtb与dtbo
android系统对dtb也有依赖,例如system、vendor等的挂载、验证。之前写过dtb与dtbo,并示范多层设备叠加层。dtb和dtbo使用分区没有固定,可以参考https://source.android.google.cn/docs/core/architecture/dto/implement
https://blog.csdn.net/dongyi1988/article/details/103995862#t1
![](https://img-blog.csdnimg.cn/img_convert/00d509eadf217b860441e7e83e15f81b.png)
5、BootConfig
BootConfig这个和cmdline一样,将配置详细信息从aboot传递到 Android 12 的机制。
现在与android相关的启动参数androidboot.*从内核 cmdline 移至 bootconfig 文件。
注意到
kernel header是V4才能用;
可在/proc/bootconfig与设备树initramfs 节点查看信息;
在linux的/proc下有文件,显然有bootconfig内核模块。
5.1、bootconfig内存使用图
![](https://img-blog.csdnimg.cn/img_convert/50dc79f6d59a47f3a30d10053b6cfac3.png)
5.2、代码解析
bootconfig结构如上图,其中parameters段有直接编译到vendor_boot镜像的固定段和bootloader启动时的附加段
mkbootimg的--vendor_bootconfig参数指定文件附加vendor_boot变成bootconfig里面的固定端,指定属性文件与编译参考地址http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Virtualization/microdroid/
vendor_boot加载后,bootloader往bootconfig内存附加参数
内核proc模块
proc-$(CONFIG_BOOT_CONFIG) += bootconfig.o
init解析成android属性
http://aospxref.com/android-13.0.0_r3/xref/system/core/init/util.cpp#249
6、总结
上面提到的ramdisk、kernel、dtb、BootConfig都进行了隔离,目前动态加载模块性能还不够。
linux解耦已经初具模型,在内容划分分区与内容加载上可能还有略微改动。
相关文章
- 一个Java程序员对2011年的回顾
- 大数据发展历程
- Android高级进阶之路【一】Android中View绘制流程浅析
- 可信服务管理(Trusted Service Manager)介绍
- GIS应用|快速开发REST空间分析服务
- 未来十年微软长盛不衰的两项战略
- 领域驱动设计模式的收益与挑战
- cocos 3.0 一键打包android平台应该注意的细节
- 数智化时代,驱动企业转型升级的“三驾马车”是什么?
- 基于MINA构建高性能的NIO应用
- 使用Rainbond实现离线环境软件交付
- 工作流引擎 jBPM 5.2 发布
- 微信小程序Minium自动化测试(三)
- 桌面应用抢先体验,这次有点料!
- 甲骨文Java专利遭拒 起诉Android侵权受挫
- 云计算的应用领域及发展前景
- Java效率真的很低吗?Android为何要采用?
- Android高级进阶之路【二】十分钟彻底弄明白 View 事件分发机制
- 庖丁解牛之-Android平台RTSP|RTMP播放器设计
- 手机直付,超级方便