LWN:LPC 2020上安卓内核相关讨论!


关注了就能看到更多这么棒的文章哦~

Android kernel notes from LPC 2020

By Jonathan Corbet
September 10, 2020
LPC
原文来自:https://lwn.net/Articles/830979/
DeepL assisted translation

在 Android 项目的早期,它的 kernel 代码跟 kernel community 的代码有很大差异。这种情况后来有了很大的改善,但 Android kernel 和 mainline kernel 之间仍然存在差异。因此,无法直接用原生内核(vanilla kernel)来运行 Android。不过,情况仍在继续改善中。在 2020 年 Linux Plumbers Conference 的 Android microconference 上,就讲述了许多这方面的进展。这几个会议都展示了在统一 Android 和 mainline kernel 方面所取得的进展,以及还有什么需要做的工作。

The generic kernel image

Todd Kjos 首先介绍了 Android Generic Kernel Image(GKI)的工作。它的目的是为了从总体上减少 Android 的内核碎片化问题。这是现有的 Android Common Kernel 的更进一步的工作,Android Common kernel 在 mainline 的长期支持(LTS, long-term support)版本的基础上,额外添加了一些 patch。这些 patch 包括 Android 特有的、没有在 kernel tree 里的一些功能,也有从 mainline 正式发布版本中挑选出来的一些 fix patch 等。因此,Android Common Kernel 与它所基于的 LTS 版本还是有一定的差异。

后面的步骤让事情变得更糟。厂商会基于这个版本的 kernel,把他们自己的改动(通常是一些重要的、设计内核核心部分的改动)加上来,生成一个 vendor kernel 版本。而 OEM(original-equipment manufacturer)在基于 vendor 的芯片来开发具体产品时,首先会使用这个 vendor kernel,在此基础上添加他们自己的更改来得到一个 OEM kernel,该内核将随产品一起交付给消费者。所有这些补丁导致每种产品都有自己的内核,这意味着实际有数千种不同的 "Android " kernel 在流通。

Kjos 说,这套做法导致很多额外的工作。这种碎片化现象使我们更加难以确保所有设备都运行最新内核,甚至很难确保它们都能获得安全更新。新的平台发布时要求要用新的 Linux kernel,这就导致现有设备升级到新的 Android 版本时需要花费更多时间来升级。vendor 和 OEM 所做的 fix patch,通常也不会合入到 mainline,这让情况变得更糟。

Android 开发者希望解决这个碎片化的问题;实现这个目标的途径是提供一个所有设备都能使用的二进制形式(binary form)的通用内核,也就是所谓的 general kernel image, GKI。任何不在 mainline kernel 中的 vendor 代码或者设备特有的代码都需要以 kernel module 的形式加载到 GKI 中。Kjos 说,这意味着 Android 明确在鼓励 vendor module,这样能得到一个更干净的内核,避免现在许多设备上都在做的对内核核心代码的修改。

这个策略已经使得更多 vendor 在积极地将他们的代码推到 upstream。这些代码往往不符合 mainline 开发者的要求,有些甚至只是把一些 kernel symbol 给 export 出来。他说,这在开发社区中造成了一些争论和冲突。

最后,他说 Android 11 的发布要求所有设备都必须使用基于 Android Common Kernel 的内核。Android 12 将要求改用 GKI 出货。Tim Bird 问道,如果 vendor 必需的一些 patch 没有集成到 mainline 或 Android Common Kernel 中时,厂商应该如何应对。Kjos 回答说,目前的计划是通过 tracepoints 添加 vendor hook。不过细节还没有制定出来。

ABI enforcement

之后,Matthias Männich 谈到了 GKI ABI enforcement,这个工作的目的是确保供 module 使用的 ABI 要稳定不变,这样 GKI 的更新就不会破坏已经发布的设备。这不是一个简单的任务,内核 ABI 非常多,很难及时发现某一部分发生了变化。他强调,这项工作绝不是要固定 mainline kernel ABI,也不是要固化 LTS kernel 的 API。其实它只是想让 kernel ABI 在给定的 Android 版本中要保持稳定。

虽然在 GKI 更新时不期望有任何 ABI 改动,但只要不改变 module 所能看到的接口,那其实还是可以改变的。kernel 和 module 都是使用同样的编译工具,经过 "hermetic build,即不受外界条件影响的编译" 的过程来编译生成的,也就是说,其中所有需要的用到的库都不会使用进行这次编译的 PC 上的本地环境的。而编译器的更新会被仔细检查,来确保它们不会导致任何 ABI 变化。他说,Android 宁可不升级也不会冒出问题的风险。

在 ABI 内部,需要确保保持所有可被看到的 API 都稳定。因此,如果这些可以被看到的 API 集合能尽量小,这个任务显然会更容易。在这方面,kernel symbol namespaces(https://lwn.net/Articles/760045/ )就会很有帮助。同时,kernel symbol namespaces 也有助于防止内核符号不小心地用到。通过观察 vendor module 实际使用到的 kernel symbol,就可以建立起一套 kernel-module interface,这些符号自然要 export 出来。不过还要把后来发现没有用到的 API,都从 GKI 中拿掉,让它无法被调用到。当厂商需要一个新的 symbol 时,就需要向 Android Open Source Project 提出请求,只要这个请求是合理的,那么这个 symbol 就会出现在后续的 GKI 更新中。

Android on mainline

Sumit Semwal 介绍的话题是关于如何在 mainline kernel 上启动 Android 系统的。结果发现,在一般的场景下,目前只需要一个 patch 就可以了:anonymous VMA naming(https://lwn.net/ml/linux-kernel/20200901091901.19779-1-sumit.semwal@linaro.org/ )。安卓内核还需要 inline encryption,但这一个功能在 5.9 版本中已经合入 mainline 了。

当然,在真实硬件上,情况会变得更加复杂。对于使用骁龙 845 SoC 的设备来说,需要一些 out-of-tree drivers。其中,Pixel 3 设备上使用的 lt9611 HDMI bridge driver 已经排入 5.10 合并窗口了。小米的 Pocophone F1 只需在 5.9-rc1 kernel 的基础上打上一些触摸屏、WiFi 和音频设备的 patch,就能正常运行了。

他说,理论上来说,Android 系统可能只需要一个 mainline kernel patch 就能启动,但 Android kernel 在 5.9-rc kernel 的基础上仍然额外增加了 485 个 patch。其中约 30 个目前正在讨论合入 mainline,78 个有计划 upstream。另外 25 个正在由 Linaro 进行开发调整也希望让它们进入 upstream。有 54 个 patch 最终会被其他替代方案取代,包括人们讨论很多次的 ION memory allocator。这样就剩下 260 个补丁目前还没有明确看到推进 upstream 的计划。其中许多 patch 与 GKI build 或 configuration change 有关。有十个补丁可以考虑 upstream,但它们也需要 upstream user 才行。

目前围绕 upstream 工作最活跃的讨论集中在 inline encryption(已经合并了)和 incremental filesystem(增量文件系统,下文将进一步讨论)等功能上。anonymous VMA naming 最早是由 Colin Cross 在 2013 年提出来进行 review 的,但现在仍未合并,目前正在进行一些努力来希望真正能合入。DMA-buf heaps 作为 ION 的替代者正在继续推进中。

还未进入 upstream 的工作也包括 DRM notifiers,在 kernel 里面没有地方会用到它(lack an in-kernel user),因此不会考虑合入 mainline,DRM notifier 的 patch 也没有提出来 review。要想能完全取代 ION,那么还需要更多 DMA-buf heap provider 才行,可是这些工作这些也缺乏 in-knerle user。要改变这种情况,就需要 vendor 把要用到这些功能的驱动程序推到 upstream 上。

Incremental filesystem

增量文件系统(incremental filesystem)是一项重要的 Android 功能,目前还没有在 mainline 上看到太多讨论。Paul Lawrence 专门为这功能举行了一次简短的会议。增量文件系统的目的是允许新下载的应用能立即启动,哪怕应用下载到设备的过程还没有完成。为了实现这一点,正在下载的文件需要显得好像它们已经存在于设备上一样,如果在从这个文件读取时所需的 block 已经下载好了,就可以成功读取出来;否则的话应用程序只能继续等待,直到这些区块可以读到。

增量文件系统上的文件是只读的,但文件系统本身不是只读的。某个文件的各个 block 可能不是按顺序准备好的,文件系统需要相应地跟踪好这些信息。这个功能是通过 stacking filesystem 的方式来实现的,也就是说,在文件最终存储的位置底层还有一个 "real"文件系统。大部分的目录操作都会直接传递到底层的文件系统,而读取时则需要分析这个文件并返回预期的数据(当然是等到相应的部分数据已经可用才行)。写入操作(只有在创建文件时才可写入)是通过一个特殊的 ioctl()调用来完成的。

这项工作在 2019 年首次发布到 mailing list 中,但它尚未得到太多的有意义回复。预计在不久的将来会有新的版本提出来,因为 Android project 正在努力将这项功能纳入 mainline kernel。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值