本文是从安卓官网总结的内核相关知识。
1. 概览
安卓内核用的也是linux(LTS),google把LTS内核和Android的一些补丁、模块结合形成自己的Android通用内核(Android common kernel,ACK)。也就是GKI, Generic Kernel Image。
相当于现在变成了一个Image,镜像了。
GKI 内核会与包含系统芯片 (SoC) 和板级代码的硬件专用供应商模块进行交互。GKI 内核与供应商模块之间的交互通过内核模块接口 (KMI) 来实现,该接口由标识供应商模块所需的函数和全局数据的符号列表组成。
一些术语:
可动态加载的内核模块 (Dynamically loadable kernel module ,DLKM)
想要为内核贡献代码:
https://source.android.com/docs/core/architecture/kernel/kernel-code
linux内核的代码规范:
https://www.kernel.org/doc/html/latest/translations/zh_CN/process/coding-style.html
以下内容是从不同章节的总结,为了看的方便,就写到一起了。
2. GKI项目-启动更改
为了帮助 GKI 与供应商组件完全分离开来,boot 分区仅包含通用组件,其中包括kernel和带有 GKI 模块的 ramdisk。
定义了新版启动头文件 (v3),用于表明符合 GKI 架构规范。GKI 版本的boot img由 Google 提供,会在测试 GKI 兼容性时取代供应商版本的boot.img。
上面这部分内容英文官网没有,找不到确切的翻译源。
boot 分区
boot 分区包括头文件、kernel以及内含启动 ramdisk 通用部分的 CPIO 归档。
boot 分区使用 v3 版启动头文件后,先前的 boot 分区的以下部分将不复存在:
第二阶段引导加载程序(second_stage boot):如果设备具有第二阶段引导加载程序,那么现在必须将相应引导加载程序存储在自己的分区中。
second_stage 好像在开机log还有,不确定是不是单独做的改动。
second_stage具体在哪个版本中去除(如果和下面的vendor_boot一样,那印象是T上),还有待学习。DTB:DTB 存储在供应商启动分区(vendor_boot)中。
boot 分区包含一个 CPIO 归档,内含以下 GKI 组件:位于 /lib/modules/ 的 GKI 内核模块
first_stage_init 及其依赖的库
fastbootd 和 recovery(用于 A/B 和虚拟 A/B 设备)
供应商启动(vendor_boot)分区
vendor_boot 分区随 GKI 引入。该分区是采用虚拟 A/B 的 A/B 分区,包含一个头文件、供应商 ramdisk 和设备树 Blob。供应商 ramdisk 是一个 CPIO 归档,其中包含设备启动所需的供应商模块。这包括用于启用关键 SoC 功能的模块,以及启动设备和显示启动画面所需的存储和显示驱动程序。
该 CPIO 归档包含:
- first_stage init 供应商内核模块,位于 /lib/modules/
- modprobe 配置文件,位于 /lib/modules
- modules.load 文件,用于指示要在第一阶段 init 期间加载的模块
bootloader程序要求
引导加载程序必须在加载完供应商 ramdisk CPIO 映像(来自 vendor_boot 分区)后,立即将通用 ramdisk CPIO 映像(来自 boot 分区)加载到内存中。解压缩后,结果是通用 ramdisk 叠加在供应商 ramdisk 的文件结构之上。
3. Android 内核文件系统支持
低级别文件系统支持
从 Android T(AOSP 实验版)开始,用户空间仅适用于 GKI 内置的文件系统。搭载不受 Google 内核团队支持的文件系统,可能会导致用户容易受到安全问题的影响,因此不建议这样做。
Android 内核团队会继续通过对齐上游长期支持渠道 (LTS) 内核来修复所有文件系统。下面的文件系统是经常会接触的,以及现在频繁更新的
- exfat(在内核 5.10 及更高版本中受支持)
- ext4
- f2fs
- fuse
- incfs
- Vfat
- EROFS
以下文件系统已废弃,仅受到有限的支持: - sdcardfs(仅在内核 4.14 及更低版本中受支持)
以前的手机都支持外置sdcard,后来没了,原来是因为google(Android)不支持了。
虚拟文件系统支持
通常情况下,支持虚拟文件系统,具体包括:
- debugfs
- overlayfs
- procfs
- sysfs
- tmpfs
- tracefs
注意:尽管支持 debugfs,但从 Android 11(R) 开始,默认情况下不会装载该文件系统。如果用户或设备发起了 bug 报告,系统会临时装载该文件系统来生成报告。
user版本默认不会装载该文件系统,userdebug版本会装载。
4. 在 Android 12 中使用 DebugFS
搭载 Android 12 且内核版本高于 v5.4 的设备必须附带 GKI 内核。
理解了之前升级到S的设备为什么要引入这一改动了,原来是谷歌的规定。
DebugFS专门用于debug的,也就是lunch xxx-userdebug.
5. 安卓内核常见问题
是否有专门针对 GKI 的测试?
供应商测试套件 (VTS) 测试用于验证是否安装了经过认证的 GKI build,以及是否遵循了每个版本的 GKI 要求。例如,谷歌为启动头文件 v3 提供了 Android 12 VTS 测试,用于验证搭载 5.10 内核的设备中是否存在所需分区。
针对GKI的配置
对gki_defconfig的所有CONFIG更改必须同时应用于 arm64 和 x86 版本,除非CONFIG是特定于体系结构的。
所以能看到两个defconfig文件,
L81A/s-vendor-pre/kernel/msm-4.19/arch/x86
https://source.android.com/devices/architecture/kernel/kernel-code#changes-to-gki-defconfig
对 gki_defconfig 的更改。
6. EROFS
https://source.android.com/docs/core/architecture/kernel/erofs
EROFS 是在 Linux 4.19 中引入的只读文件系统。它支持压缩和去重,并针对读取性能进行了优化。
EROFS文件系统(英文名:Enhanced Read-Only File System )是一个Linux操作系统下的只读文件系统,用来在保证嵌入式设备端到端的性能下节省存储空间,尤其是Android设备。相比其他通用文件系统,它使用了减少元数据的设计,并且提供透明压缩技术给目标文件系统用户。
百度了一下,这是华为研发的,提交到了开源社区里面。
编译时的调整:
BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := erofsBOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := erofsBOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := erofsBOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := erofsBOARD_VENDOR_DLKMIMAGE_FILE_SYSTEM_TYPE := erofsBOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE := erofs