​​Android和Linux:你俩到底啥关系

最近正在着手研究android,自己虽然还算是熟悉Linux,但对Android可是一窍不通,都说Android就是个装了UI的Linux,可到底和Linux有什么关系呢?

根据Linux官方文档,Android分为以下几层:

  • 应用框架。应用框架最常被应用开发者使用。作为硬件开发者,您应该非常了解开发者 API,因为很多此类 API 都可以直接映射到底层 HAL 接口,并可提供与实现驱动程序相关的实用信息。
  • Binder IPC。Binder 进程间通信 (IPC) 机制允许应用框架跨越进程边界并调用 Android 系统服务代码,这使得高级框架 API 能与 Android 系统服务进行交互。在应用框架级别,开发者无法看到此类通信的过程,但一切似乎都在“按部就班地运行”。
  • 系统服务。系统服务是专注于特定功能的模块化组件,例如窗口管理器、搜索服务或通知管理器。应用框架 API 所提供的功能可与系统服务通信,以访问底层硬件。Android 包含两组服务:“系统”(诸如窗口管理器和通知管理器之类的服务)和“媒体”(涉及播放和录制媒体的服务)。
  • 硬件抽象层 (HAL)。HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现。借助 HAL,您可以顺利实现相关功能,而不会影响或更改更高级别的系统。HAL 实现会被封装成模块,并会由 Android 系统适时地加载。如需了解详情,请参阅硬件抽象层 (HAL)
  • Linux 内核。开发设备驱动程序与开发典型的 Linux 设备驱动程序类似。Android 使用的 Linux 内核版本包含一些特殊的补充功能,例如低内存终止守护进程(一个内存管理系统,可更主动地保留内存)、唤醒锁定(一种 PowerManager 系统服务)、Binder IPC 驱动程序,以及对移动嵌入式平台来说非常重要的其他功能。这些补充功能主要用于增强系统功能,不会影响驱动程序开发。您可以使用任意版本的内核,只要它支持所需功能(如 Binder 驱动程序)即可。不过,我们建议您使用 Android 内核的最新版本。如需了解详情,请参阅构建内核一文。

对我来说比较关心的就是Android的kernel采用的还是Linux kernel,但很明显Android加入了自己的东西,对Linux进行了一些修改。于是我开始思考,那Android开发是如何进行的呢?Android 10、11、12和哪些Linux kernel版本相对应?这便是今天的主题。

Linux kernel release

目前需要先讲述一下Linux目前开发版本的分类,主要分为四部分:

  • Prepatch

    由Linus Torvalds维护和发布,针对Mainline kernel添加了新的feature,主要供Linux开发者和狂热爱好者进行测试。后面有-rc+数字的版本就属于Prepatch版本,一般来说数字最大为7,rc7为最后一个prepatch版,之后就会出现下一个mainline版本。prepatch版本一般一星期更新一次。

  • Mainline

    Mainline tree由Linus Torvalds维护,每一个Mainline kernel一般9到10个星期会发布一个新的版本。

  • Stable

    每一个mainline kernel发布后,就被认为是stable的。比如目前正处于v5.17-rc6的开发中,上一个mainline版本v5.16就被认为是最新的stable版本,对于stable版本的bug fix需要邮件发送给该版本的maintainer,在github上面提交PR是不可行的:-)。

    在下一个mainline内核可用之前,通常只有几个错误修复内核版本,除非它被指定为“长期维护内核”(Long Term)。Stable内核更新根据需要发布,通常每周一次。

    稳定版本的编号开头为内核版本编号,末尾再添加一个数字。例如,Linus 发布了 4.4 内核,则基于此内核的稳定内核版本编号为 4.4.1、4.4.2、4.4.3,依此类推。表示稳定内核版本树时,该序列号通常简写为 4.4.y。每个稳定内核版本树由一位内核开发者维护,该开发者负责为该版本挑选所需的补丁程序以及管理审核/发布流程。

    稳定内核的维护期限为当前开发周期。Linus 发布新内核后,上一个稳定内核版本树就会停止维护,用户必须转为使用新发布的内核。

  • Longterm

    很多不同的 Linux 用户都表示希望延长对内核的支持,而不只是几个月时间。因此,长期维护(LTS) 内核版本应运而生,第一个 LTS 内核 (2.6.16) 在 2006 年发布。从那时起,每年都会选择一个新的 LTS 内核,并且内核社区会为该内核提供最少 2 年的维护支持

最后需要提一下版本号这个东西,因为看一些早期的书籍,一直告诉我们版本号的奇偶具有含义,类似于w.xx.yy这种版本号,xx被称为major revision,yy被称为 minor revision,xx如果为奇数表示为开发版本,为偶数代表稳定版。但这个规则在2004年随着2.6版本的出现废弃了,版本号什么也不代表,只是单纯的数字罢了。

Does the major version number (4.x vs 5.x) mean anything?

No. The major version number is incremented when the number after the dot starts looking "too big." There is literally no other reason.

同时minor revision也被废弃,从3.0版本开始后,就没有minor revision这个东西了。我们看到的minor revision属于稳定版本编号中的,mainline版本不再具有。总之现在的版本号没什么特殊含义。

个人感觉Linux的开发流程为Linus维护着Mainline版本,然后发布Prepatch进行测试,随着测试结束和时间的推进,发布下一个Mainline版本,同时也成为新的稳定版,由对应的维护人员来管理针对该稳定版的bug,并进行更新,而Linus选取合适的feature继续下一个prepatch版本的构建和发布,不负责稳定版的bug report。类似于下面两条线

5.16->5.17-rc1->5.17-rc2...(Mainline开发,Linus 负责,两三个月新版本)

|--5.16.1--5.16.2--5.16.3....(Stable开发,专门Maintainer负责,两三个月结束)

Android kernel

说完Linux,我们要来说一下Android。

由于各版本之间发生了大量更改(每个版本有 10000-14000 项更改),因此包含大型补丁程序集的基于 Linux 的设备在更新到新版内核时可能会遇到严重问题。因此,大多数 SoC 供应商开始使用 LTS 版本对其设备进行标准化,使这些设备能够直接从 Linux 内核社区接收错误和安全更新。Android同样采用LTS kernel来更新设备内核。

AOSP 通用内核(也称为 Android 通用内核或 ACK)是 kernel.org 内核的下游,包含与 Android 社区相关但尚未合并到 Mainline 内核或长期支持 (LTS) 内核的补丁程序。这些补丁程序可能包括:

  • Android 功能所需的向后移植和精选的上游功能
  • 可供 Android 设备使用但仍处于上游开发阶段的功能(例如,Energy Aware Scheduler 任务放置优化)。
  • 对其他生态系统合作伙伴有用的供应商/原始设备制造商 (OEM) 功能(例如,sdcardfs)。

android-mainline 是 Android 功能的主要开发分支。每当 Linus Torvalds 发布内核版本或候选内核版本时,Linux Mainline 内核就会合并到 android-mainline 中。在 2019 年之前,Android 通用内核是通过克隆最新声明的 LTS 内核并添加 Android 专用补丁程序来构建的。2019 年,这一过程变成了从 android-mainline 中分支出新的 Android 通用内核。这种新模型以递增的方式构建内核,从而避免进行大量的向前移植和测试 Android 补丁程序的工作。android-mainline 会经过大量持续不断的测试,因此该模型可保证内核自发布之日起就具有很高的质量。

当上游声明新的 LTS 时,相应的通用内核就会从 android-mainline 分支出来。由于通用内核来自于android-mainline,厂商可以在上游声明 LTS 版本之前,通过从 android-mainline 进行合并来开始项目。创建新的通用内核分支后,合作伙伴可以将合并来源无缝更改为新的分支。

其他通用内核分支从其关联 LTS 内核接收定期合并。这通常会在 LTS 版本发布后立即执行。例如,Linux 4.19.64 发布后,便会合并到 4.19 通用内核(例如 android-4.19-q)中。强烈建议合作伙伴定期执行从通用内核到其产品内核的合并,以便及时获取最新的 LTS 和特定于 Android 的问题修复。

总结一下,可以理解为android-mainline跟随着Linux kernel的mainline同步前进,每当一个LTS版本的内核发布,就会从mainline中分出一个对应的通用内核分支,来跟随该LTS版本前进,每当LTS版本更新时,新的release就会被尽快合并到对应的通用内核分支,通用内核中包含与 Android 社区相关的的补丁程序。

现在我们已经知道Linux kernel发展和Android中的通用内核发展之间的关系了,那Android platform release(Android 10、11、12这种)和Android中的通用内核有什么关系呢?

功能内核和启动内核

目前 Android 通用内核也分以下两种:

  • 功能内核

    包含最新 Android 平台版本功能的增强内核称为功能内核。对于 Android 11,功能内核基于内核版本 4.14.y、4.19.y 和 5.4.y。在过去的平台版本中,功能内核与启动内核相同。但在 Android 12 中,将有两个功能内核和三个启动内核。

  • 启动内核

    指定的启动内核可用于启动搭载特定 Android 平台版本的设备。对于 Android 11,可以使用基于内核版本 4.14.y、4.19.y 和 5.4.y 的内核启动设备。

每个 Android 平台版本都支持基于三个 Linux 内核版本中的任何一个启动新设备。如下表所示,Android 11 的启动内核为 android-4.14-stableandroid-4.19-stableandroid11-5.4

由于更新平台版本时通常不需要升级内核,因此缺少平台版本最新功能的内核仍然可以用来启动设备。因此,即使设备上的平台版本已升级到 Android 11,为 Android 10 设计的内核(例如 android-4.19-q)也可以在设备上使用。从 Android 12 开始,为了控制必须支持的稳定版 KMI 的数量,功能内核的数量将少于启动内核的数量。

通用内核分支类型

通用内核分支目前分为以下三种

  • KMI kernel branch(目前)

    KMI kernel有着稳定的kenel Module Interface,KMI通过内核版本和Android platform release来定义,所以分支按照 <androidRelease>-<kernel version>来命名,比如Android 11的5.4 KMI内核被命名为android11-5.4.。对于Android 12来说,还有两个额外的KMI kernel:android12-5.4android12-5.10.

  • legacy(以前)

    • dessert kernel branch

      只有启动内核才会创建dessert kernel,只接受来自LTS的合并,不添加新的feature,比如android-4.9-q 只接收LTS 4.9.y 分支的合并。

      因为Android 11抛弃了dessert命名,所以本该命名为android-4.14-randroid-4.19-r的分支现在称为android-4.14-stableandroid-4.19-stable.从Android 11开始支持KMI kernel而不是dessert kernel,所以命名换成了上面说的KMI命名。

    • release kernel branch

      针对每一个启动内核出现新的Android platform release时进行创建release kernel,当对应的kernel或platform release被抛弃时,该分支也会被抛弃。他们不接受LTS的patch,所以minor number从不发生变化,只在每个月Android Security Bullentin发布时,进行bulletin上patch的更新。

      但是在Android 11和之后的平台,合作伙伴必须从 dessert 或 KMI 内核进行合并,才能应用 Android Security bulletin 中引用的补丁程序,因为对于 Android 11 或更高平台版本,不会再创建发布内核。

上面都是来自于Android官方文档中的内容,有些概念实在过于绕。个人理解,一个Android平台可对应多个通用内核(一般是三个),通用内核分为功能内核和启动内核,如果是Android 11及以前,我们可以对功能内核和启动内核不做区分。还有一些通用内核层次结构、KMI分支生命周期、内核兼容性的问题可以参考官方文档

目前我们大体了解了Linux和android之间的关系。总结一下就是,Android底层的kernel基于Linux kernel,维持了一个android-mainline分支和上游的Linux kernel mainline同步(该主线由Linus维护,经过9-10个周期会发布新的版本,期间会进行prepatch版本的发布,用来测试),每当一个新的LTS版本确立后,就会从android-mainline中分支出对应的通用内核分支,加上针对android社区的补丁程序,形成通用内核,每当上游的LTS版本更新时,该分支也会进行合并,不同的通用内核根据上层的android platform release进行相关工作,用于启动不同的android平台。例如4.14版本的通用内核针对android 10和android 11会有android-4.14-qandroid-4.14-stable两个分支,但其内部都是基于Linux kernel v4.14.x这个LTS分支。我们可以根据adb输入uname -r 来了解手机内部的Linux kernel版本,之后寻找通用内核分支版本进行源代码的查看。

posted @ 2022-03-05 19:33  扶磐  阅读(1382)  评论(0编辑  收藏  举报