LWN: 监控kernel内部的ABI

640
点击上方蓝色“ Linux News搬运工”关注我们~

Monitoring the internal kernel ABI

By Jake Edge


LPC

在Linux Plumbers Conference 2019会议的Distribution Kernels microconference议题里,Matthias Männich 介绍了一下Android项目是如何监控kernel ABI的改动的。随着Android的kernel版本不断演进,经常会使用到kernel新版本里引入的新功能以及bug fix,所以Android希望能确保ABI保持不变,这样相关module仍然可以拿来就能正常工作。这个话题主要是介绍Android相关的工作,不过这里的技巧和工具也能用在其他的发行版上(例如商业发行版)。

Männich 是Google Andriod kernel团队的一员,不过他接触Linux kernel的时间并不长,他的背景主要在编译系统(build system)这方面。他专门强调他的演讲并不是指kernel暴露给user space的ABI,而是指kernel暴露给module的ABI、API。目标是能让Android kernel的生命周期里保持ABI不变。他知道有一些其他发行版多年来一直都是按照这个标准做的,不过Android kernel和build系统跟他们很不一样,解决方案也值得分享一下。

Out of tree

他说,有些情况下不可能把所有信息都放在代码tree里,这个现实情况导致了后面的一系列工作。ABI稳定就意味着能够把kernel和module的开发过程分隔开。最终目标是希望能通过通过给module生态环境提供统一的ABI来支持多种不同kernel版本,从而减少Android各种方案的碎片化。

LWN: 监控kernel内部的ABI_第1张图片

从Android 8开始,Project Treble就把vendor相关的Android代码跟其他软件代码分离开了,不过vendor的driver还是和kernel公共代码混杂在一起,没有完全分隔开。在此之后,kernel部分就被塞到了generic kernel image(GKI)里,此外还有统一的GKI module,以及使用稳定的ABI/API访问GKI的硬件相关驱动程序。

稳定的接口在upstream mainline这边其实并不需要,而是要对基于长期稳定版本(LTS)的分支代码来做这件事情。Dhaval Giani问道是否目标是希望让4.9.x和4.14.x都有同样的接口,Männich澄清说目标只是在一个LTS branch内部保持稳定即可。也就是说所有运行4.19.x系列的Android kernel都可以互相兼容,而无法跟5.x kernel兼容。

K. Y. Srinivasan问了个问题,Google是否已经放弃了之前的强迫所有内部开发者把代码upstream的宗旨。Männich说公司仍然鼓励这么做。Greg Kroah-Hartman指出他很希望所有人都把代码推到mainline上来,大家应该去跟高通好好谈谈。而Android项目经常需要跟一些没有进行upstream的vendor合作,所以没法避免,这就是现实世界的麻烦之处,他也在想办法解决。Tim Bird问Greg是否计划在LTS branch上只合入满足某些前提条件的改动,Kroah-Hartman说没这个打算。

实现方法上来说,Android会需要找到一个kernel configuration能够让所有vendor都可用。目前Android还没有办法能让每次的build结果都可以复现(reproducible build),因为目前Android的kernel编译还是一个封闭系统,也就是说编译时使用的toolchain、依赖文件、工具(例如uname)等都是独立的包,跟Android其他模块的编译不是同一套工具。

为了减少影响范围,首先需要能定义清楚ABI包含哪些。这包括一些白名单以及一些黑名单,也还有一些其他机制来帮助。

目前,Android只支持android-4.19和andriod-5.x(还没定具体x是哪个版本)两个系列上的稳定ABI。kernel会有一个GKI configuration,不过每个体系架构上可能会有不同。只支持这个封闭编译环境里的Clang编译器,也就意味着编译器和相关工具不能随意跟着Android kernel版本来升级。

稳定ABI只会覆盖可见的ABI。也就是说并不会审查代码里的各个ABI,而只是确保kernel作为可执行二进制程序对外的ABI。开发者目前正在做白名单,不久之后symbole namespaces合入mainline之后就能够根据不同的namespace来定义有哪些稳定ABI是被支持的。

一位听众想知道其他发行版是否也关注这个稳定ABI的问题。其他几位听众回答说有些人确实在意,因为客户会在意这一点。Laura Abbott举了个例子,一个流行的显卡驱动,没有提供源代码,所以无法重新编译module来配合新升级的kernel。有很多不在kernel tree里的驱动程序,他们的开发者可以升级驱动程序,不过如果发行版供应商希望能确保这些驱动程序都能持续正常工作的话,就需要能确保ABI稳定不变。

libabigail

Android利用libabigail来分析kernel ABI。libabigail包含一个library库,也包含对应的一套工具软件。Android基本上只用这些工具来提取kernel和module二进制文件里的ABI描述,并进行序列化操作(serialize/deserialize)。本来libabigail只使用了ELF和DWARF信息,不过近来也支持了分析kernel里的ksymtab,而不仅仅是看ELF符号表了。它接着会在内存里生成数据结构,列出它找到的ABI。这个数据结构会被序列化成XML文件,直接跟其他版本的ABI xml文件对比即可。

Bird问这个工具是不是应该加到upstream kernel的Makefile里。Kroah-Hartman和Männich都觉得这会导致kernel编译会依赖一个第三方工具,很多人可能不喜欢这个做法。Männich觉得不如在kernel编译完之后直接调用这个工具,这样更加简单。

Giani问是否需要所有可见的ABI都要在两个版本之前完全一样。Männich指出这就是为什么需要有白名单和suppression(忽略名单)机制了。Giani建议完全可以仅依赖一个白名单来解决这个问题,因为Android项目知道所有的驱动程序以及硬件相关的需求信息。否则的话,今后支持的ABI可能会不断增长,其实并不需要比对这么多的ABI。

Männich说,Android kernel configuration其实并不算大。比起一些发行版的标准configuration其实小多了。此外他也希望symbol namespaces合入之后能大大简化选择哪些ABI的过程。另一位Android team成员补充说,如果仅仅只用一个白名单的话,那么某些ABI其实我们根本不关注,例如文件系统接口,不过这些接口可能定义了一些结构或者数据类型用在了其他地方。所以目前的工作流程是尽量能拿掉一些东西,来让稳定ABI的list变的更小。

Ben Hutchlings问道,有些ABI的改动其实是向后兼容的,这些是怎么处理的?Männich回答其中一些仍然在处理。libabigail维护者Dodji Seketeli回答说有个suppression机制可以用,有点类似Valgrind中的相同机制。Suppression机制可以指明哪些改动已知不会产生ABI兼容性问题。

Sasha Levin问道,有些内核改动不会被视为ABI改动,例如锁的管理API。这些也会被跟踪对比吗?Männich说目前这些还没处理好,正在进行中。他举了一个例子是untagged enum值被作为作为函数的整数返回值,假如enum的值定义被重新调整过了,那么ABI其实已经变了,不过libabigail不会报出来。Seketeli认为应该把所有type都加到这个工具对ABI的跟踪列表里,而不应该只是跟踪函数定义。不过目前没这么做,主要是希望能降低内存占用。

另一位Android项目开发者指出,通常来说,像锁获取这些定义在LTS branch上一般不会有改变。如果你希望确保锁获取这些ABI稳定,那么就需要关心所有的ABI,这其实有可能会有一些其他问题,目前只能依靠开发者自己来识别这些问题,毕竟工具目前还无法提供这方面的帮助。

时间不多了,Männich快速介绍了一下ABI相关的工具是怎么集成到Android编译流程里的。任何人如果编译Android kernel都会在repo sync更新代码tree的时候拿到toolchain和工具,包括libabigail。在完整编译过程中,就会自动生成ABI列表,并跟基准ABI比对过。所有对ABI进行的改变都会在Android使用的Gerrit代码review系统上着重显示出来。这些工具很通用,应该会很容易集成到其他项目的工作流程里。

[I would like to thank LWN's travel sponsor, the Linux Foundation, for travel assistance to Lisbon for LPC.]

全文完

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

极度欢迎将文章分享到朋友圈 
热烈欢迎转载以及基于现有协议修改再创作~

长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~

640?wx_fmt=jpeg

你可能感兴趣的:(LWN: 监控kernel内部的ABI)