Android Q新特性:APEX 模块化升级

最近在修改Android源码(厂商定制的源码,非AOSP)时,遇到了一些问题:

  1. 新增的lib库模块,需要依赖libart等so包,而这些so包在Android Q中被编译到了apex中(apex文件位于/system/apex目录),导致无法找到共享库(需要修改/system/core/roodir/etc/ld.config.txt, 修改里面的策略比较麻烦,并且可能导致安全问题)。
  2. 在将java层代码移动到了core-libart中,可以顺利的引用到com.android.runtime.release中的库文件,也算解决了问题1。
  3. 在某个最新的Android版本中,system分区为erofs文件系统(只读),无法通过adb remount来重新挂载为可读写。而为了替换apex,需要替换/system/apex/下的相应文件。该系统版本通过引入了overlay文件系统来解决该问题。overlay文件系统在system挂载点上覆盖了一层upper目录。当用户通过adb remount指令重新挂载后,所有对/system的操作实际是对cache下的upper目录的操作。由于cache分区太小,导致将文件直接放入。
  4. 在厂商定制的Android源码中,由于存在很多二进制交付的部件,这使得单纯通过编译源码得到的System.img是不完整的镜像,无法直接刷入设备。

解决方案

为了将修改后的APEX文件放入设备中,考虑到APEX特性主要用于模块化升级操作,肯定预留了升级模块的功能。故而,可以利用APEX的升级功能来达到替换APEX的效果。
接下来,我们将对APEX进行简要的学习。相应的源码位置如下

  1. APEX的实现源码位于:/system/apex/模块
  2. 与运行时库相关的APEX编译模块(com.android.runtime)位于art/build/apex模块,编译指令为:make com.android.runtime.release, 编译后替换/system/apex/相应文件,重启后将在/apex中挂载。

参考资料

APEX简要介绍

APEX是Google继Project Treble后的又一重大举措,它是Android Q的系统组件更新机制。APEX的想法在GNU/Linux发行版中非常普遍:针对Linux库集合中的特定部分的包更新。但这是Google从未尝试过的事情,因为Android中使用了一个ro(只读)分区,在其中存储了所有系统库和框架,而不是大多数Linux发行版中通常使用的rw(读写)分区,从而使得其难以实现标准升级过程。
库是预编译的代码,可以在其它程序中使用。常用的方法是可以制作成Android应用程序调用的库,减少Android应用程序的大小,因为不需要在多个应用程序中实现相同的代码。我们可以在/system/lib/system/lib64目录中找到许多预装系统库。Android系统库通常不会单独更新-相反,它们会通过OTA更新作为Android平台升级的一部分进行更新(备注:意思就是要整个系统升级才能把系统库部分也一并升级了,而不能像Linux那样子,可以针对特定的系统库进行升级)。另一方面,Linux发行版的库可以单独升级。
随着APEX的推出,Android中的系统库可以像Android应用程序一样单独更新。这样做的好处是,应用程序开发人员将能够利用更新后的库,而无需等待OEM推出完整的系统升级。
APEX是一个生态系统,迫使Google重新考虑Android从不同于/system的非标准分区加载所有库和文件的方式。
首先,我们必须区分共享库和静态库。共享库是一个库(如libkind.so的文件),它不包含自身运行所需的所有代码,而是与实际提供代码的其它库进行链接;静态库则是,可以认为它不依赖于其它任何库,并在文件中静态包含了所有内容。
Android历史上使用了名为ld.config.txt[0]的单个配置库路径文件(即Linux中的LD_LIBRARY_PATH),以配置二进制或其它库中所需的共享库的允许搜索路径。这些路径在配置中是硬编码的,不可扩展。除非用户安装OTA Android更新,否则此布局(包括只读系统分区)会导致不可更新的库。Google解决了该问题,允许扩展搜索路径,让单个APEX包提供自己的ld.config.txt,其中包含额外(和更新)库路径。
但这样子仍存在问题:首先是ABI(应用程序二进制接口)稳定性,库应该始终导出一组稳定的接口,以允许其它应用程序和库继续使用相同的协议,即使升级后的库也是如此。Google正尝试在APEXed库之间创建稳定的C接口来积极开展该工作。
APEX并不仅与库和二进制文件。实际上,它还包括配置文件、timezone更新以及一些java框架。
当前AOSP提供的APEX包名的示例有:

  • com.andrid.runtime: ART和bionic runtime(二进制和库)
  • com.android.tzdata: TimeZone和ICU数据(库和配置数据)
  • com.android.resolv: Android中用于解决网络相关请求的库(库)
  • com.android.conscrypt(Java安全提供程序)(Java框架)

如何安装和构建APEX包

APEX软件包是一个简单的Zip包(如APK),可由ADB进行安装,而后通过包管理器来安装。

image.png

apex_manifest.json指定了package以及version:
image.png

apex_payload.img是一个micro-filesytem 镜像(EXT 4格式)

image.png

其它文交所 用于安装软件包是的验证过程的一部分,如:

  • AndroidManfest.xml:
  • META-INF/目录有着包整数,并使用域APK相同的机制。因此,在运行用户安装更新之前,这些包在运行时,将由私钥/公钥对进行验证。Google又增加了2层安全性,它们使用dm-verity检测镜像的完整性以及AVB(Android Verified Boot)验证来确保镜像来自可信的源。最坏情况下,APEX包将被拒绝。
    如果所有验证步骤都成功,镜像文件将被标记为有效,并在下一次重新引导时替换系统实体。

如何在启动时安装镜像

image.png

预安装的软件包存储在/system/apex中,并且所有软件包当前都是版本1.但当APEX被激活时会发生什么?我们将再次使用com.android.tzdata做例子。


image.png

让我们重启设备并分析logcat。


image.png

前两行提供了足够的信息来了解软件包的来源与安装位置:/apex/, Android Q引入而来新的目录,用来存储激活的软件包。
使用AVB成功验证软件包后,并且公钥匹配后,使用loop设备将APEX安装到/dev/block/loop0,使系统可以访问EXT4文件系统。loop设备是一种伪设备,它是文件可以作为块设备被访问,使得该文件的内容可以作为安装点被访问。
此时,由于@1后缀(表示软件版本),APEX仍未使用。为了最终让系统知道我们的软件包已经激活,它将被绑定挂载到/apex/com.android.tzdata。其中Android主动期望tzdata生效,绑定装载覆盖不同点下的现有目录或文件。


image.png

APEX的实现整个位于AOSP下的单个仓库。apexd(APEX daemon)目录含有Android上运行的代码。apexer目录含有构建系统使用的用来创建APEX包的代码。
Google视图创建一组APEX包的核心集,这些包可被Google更新,从而可以创建一个在供应商之间共享的统一的Android基础核心,使的只有"system"更新称为可能,但只是单个包的升级。
apexd要求 /data/apex在启动后立即可用,以更新所有的Android模块。使用FDE(全潘加密),/data/apex/在用户解锁设备之前都是加密的,使得apex基本上毫无用处,因为只有系统apex的变种会在启动时加载。除此之外,所有设备都应该支持APEX,但他们需要一些内核补丁。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350