Android 内核的开发“顽疾”如何解决?

【CSDN编者按】众所周知,安卓设备是基于Linux内核开发的,但却不是主线版本的内核,这就导致了安卓设备不仅会限制使用新的Linux内核特性,还会带来更新速度慢、大量代码使用、没有持续集成过程等问题。这也就意味着,安卓内核的开发和管理方式消灭了许多Linux的优势。因此,消除安卓设备的古老内核问题迫在眉睫且任重而道远。

Android 内核的开发“顽疾”如何解决?

以下为译文:

安卓设备基于Linux内核,但从一开始,那些设备就没有运行主线版本(mainline)的内核。

那些设备上运行的不属于主线的代码非常多,而大多数时候,人们认为这是个问题,所以人们花了大量资源尝试减少这些代码。在2018年LPC大会(Linux Plumbers Conference)上,Sandeep Patil讨论了这个问题以及计划的解决方法。尽管在安卓设备上运行主线内核的梦想还没实现,但可能比多数人想像得要近一些。

他说,安卓内核始于主线的一个长期稳定版本(LTS),那些发布与内核中的安卓特有代码合在一起组成了Android Common Kernel的发布。厂商会选择一个common kernel,然后加上更多的主线之外的代码,以生成专用于某个系统芯片(SoC)的代码,然后发布给设备制造商。最终,某个SoC内核会被冻结,而冻结之前可能又会加入大量主线之外的代码,然后用于某个特定设备型号的内核。现在,虽然从LTS到Android Common Kernel的代码合并每隔几周就会进行一次,但主线内核真正进入设备仍然需要好几年时间——这也是安卓设备一直在运行古老内核的原因。

这个过程会导致很多问题。

安卓内核必须能够运行多种古老的Linux内核,这个限制导致很难使用新的Linux内核特性。Linux内核的更新速度很慢,而且很多时候根本不存在。大量主线外代码的使用(大概有几百万行)使得合并新的Linux稳定版更新变得非常困难,甚至即使可能,将合并后的结果发布给制造商也会让他们感到害怕,所以经常不会有这种合并。安卓内核也没有持续集成过程,也不可能在主线内核之外运行安卓系统。这一切都是说,安卓内核的开发和管理方式消灭了许多Linux的优势,但人们已经做了许多努力来解决这些问题。

至于旧的内核,Oreo发布要求使用3.18、4.4或4.9内核,与之前的发布相比是个进步,因为之前的发布根本没有内核版本要求。

Pie发布进一步缩小了内核版本的要求,它要求设备必须用4.4.107、4.9.84或4.14.42(或每个版本的最新稳定版本)。

安卓开发者试图通过强迫制造商使用特定版本来改进这个问题。这的确收到了效果,但基础的内核版本依然是两年前的(甚至更久),而Android核心依然要兼容3.18版Linux内核。

......

Patil注意到,一些人担心稳定版更新后的bug回归问题,但在采用那些稳定版之后两年多的时间,安卓项目只遇到过一次bug回归问题。具体来说,4.4.108会导致问题,因此当时只要求4.4.107版。其他情况下,已证明稳定版更新对于安卓系统十分可靠。

原因之一可能是持续集成测试的改善。例如,现在LTS、-rc和Android Common Kernels都在运行LKFT。很多的测试都是通过KernelCI进行的,而安卓开发者也在为Linux Test Project做贡献。内核不定会在一台名为Cuttlefish的模拟器上通过整个提交前的测试流程,该模拟器可以运行安卓和主线内核版本。更多的测试由SoC厂商负责,但从未有人报告过LTS内核更新导致的问题。当然他们会在合并主线外代码时遇到冲突,但这是预料之中的。

即使如此,内核更新对于安卓厂商依然是个大问题,他们非常担心将大量改动发布到已发布的设备上。因此设备一旦发售,一般就不会再更新内核。虽然这种情况很糟糕,但至少比几年前某个SoC一旦进入生产后就不能更新内核要好一些。但Google计划继续敦促设备制造商发布更新,最终希望设备即使在发售之后也能强制更新到最新的LTS版本。在某个点上,LTS发布将被包含在安卓的安全公告板上,因为修正所有bug的确有实际的价值。Patil还引用了Greg Kroah-Hartman的话说,没有所谓的“安全bug”,只有“bug”,而且所有bug都应该被修复。

设备无法更新主线内核的问题依然存在,其原因当然都是因为主线之外的代码。不过经过努力之后,在Android Common Kernel中,这部分代码的数量已经大大减少。现在Android Common Kernel中只有大约30个补丁,总共增加约6500行代码就能启动安卓系统。最终的目标是将这个数字变成零,但目前还有一系列问题需要处理,包括解决绑定器的优先级继承问题,将考虑能源的任务管理并入主线,将SDCardFS文件系统桥推到上游等

他说,Treble项目引入了一个新的“厂商接口”API,可以实现一种硬件抽象层。与这个接口同时出现的还有“通用系统镜像”的概念(generic system image,GSI),它是AOSP(Android Open Source Project)的一种构建,能够在任何安卓设备上启动。如果GSI能在特定设备上启动,那就说明厂商正确实现了厂商接口。

目前,内核被认为是厂商接口的一部分——厂商必须将内核作为底层实现的一部分提供,但计划是让安卓提供基于主线内核的通用内核镜像,设备只需要运行该内核。为了实现这一点,厂商需要提供一系列内核模块,并添加必要的硬件支持。实现这一点需要将内核符号命名空间和其他东西推到上游。

这种设计显然不会消除主线外代码的问题,因为那些模块在大多数情况下并不会来自主线。但这依然是个巨大的变动:厂商特有的代码将被放到可加载模块中,因此厂商不能再修改内核。例如,以后厂商就不能再开发自己的CPU任务管理系统;所有主线之外的代码必须通过正常的模块接口与通用内核镜像合作。这样能强迫代码变得更容易向上游移动,这是正确的发展方向。

最后,Patil说,安卓内核团队在激进地试图将代码移动到上游。现在有新的方式来积极地报告脆弱性和其他问题,并与上游协作以解决问题。在此之上,项目还有许多目标,比如将ashmem和ion模块移到staging树之外,改善安卓对于设备树的使用,等等。但事态在朝着好的方向发展,总有一天我们可以克服“安卓问题”。

原文:https://lwn.net/SubscriberLink/771974/ade4e5fb18058302/

作者:Jonathan Corbet

译者:弯月,责编:郭芮

相关推荐