【问题标题】:Reducing AOSP kernel image size减小 AOSP 内核映像大小
【发布时间】:2020-08-05 15:51:01
【问题描述】:

我正在尝试构建一个 AOSP 内核,但我无法使生成的 boot.img 小到足以刷新和启动它。它包含带有附加 dtbs 和 initramfs 的压缩内核。我的意图是使用Syzkaller 对驱动程序进行模糊测试。我目前正在使用 Pixel XL (marlin)。我使用内核分支android-msm-marlin-3.18-pie-qpr3(也尝试过相关的)并且我正在尝试各种基于 gcc 的工具链。对于 AOSP,我选择了 Pie(标签 android-9.0.0_r46,构建 PQ3A.190801.002)。但是,请注意,这是一个一般性问题,它不是 fuzzing-、 kernel- 或 device-specific。

我的要求是:

  • 保留供应商引入的驱动程序(因为它们是我想要模糊的)

  • 启用 KASAN 和 KCOV(及其依赖项)

  • 启用CONFIG_DEBUG_INFO

  • 保留printk之类的

我尝试过的事情和我的想法:

  • 调整内核配置 - 这在一定程度上有所帮助,但还不够。例如,我已经在使用CONFIG_CC_OPTIMIZE_FOR_SIZE=yCONFIG_CORE_SMALL=yCONFIG_NET_SMALL=yCONFIG_KASAN_OUTLINE=yCONFIG_TRIM_UNUSED_KSYMS=yCONFIG_SLOB=y、...

  • 使用 xz 或 lzma 压缩内核(和/或 initramfs) - 这个想法似乎很有希望。我注意到 arm64 的内核构建系统既不支持开箱即用的 xz 也不支持 lzma(不知道为什么?),所以我自己修补了它来构建它。构建成功,生成的 Image.xzkern-dtbImage.lzma-dtb 似乎没问题,但是在尝试启动它时(串行调试日志):

[5710] partition_enable_wp: group 0 not defined
[5720] DTB offset is incorrect, kernel image does not have appended DTB
[5720] Device info 0x00000131/00010001/0x00010001/0, pmic 0x20009/0x455013/0x0/0x0
[5740] ERROR: Appended Device Tree Blob not found
[5740] panic (frame 0x83a86848):
...

我验证了 DTB 存在并且内核已按预期压缩。我的问题是:有可能吗? Android 引导程序甚至支持 xz/lzma 吗?我几乎没有在网上找到任何有关此的信息。有没有办法使用 xz 或 lzma 压缩内核来启动 Android?

  • 调整引导分区的大小 - 这似乎很难,但可能,不确定是否值得尝试。您能为此推荐任何资源或工具吗?

  • 从 initramfs 中删除不必要的功能

  • 链接时间优化 - 无论我使用什么 gcc 版本,我都无法让它与 AOSP 内核一起工作。有什么建议吗?

  • 将功能构建为模块而不是内置 - 我尝试的任何配置都不会成功构建,即使仅将单个功能构建为模块(具有不同的编译器或链接器错误)取决于配置)。您有任何指南或提示吗?

我还按照 AOSP 主页 (link) 上的使用 KASAN 和 KCOV 构建像素内核的教程进行操作。我遇到了一些问题,但最终(使用 Linaro GCC 5.5.0,进行了一些配置更改并且没有 CONFIG_DEBUG_INFO)我可以构建和启动它。作为概念验证很好,但不是我需要的,因为我不得不跳过一些必需的功能。

我几乎陷入了困境,并且已经在这个问题上花费了几个星期。还有其他选择吗?我很乐意以任何方式启动它。我很乐意提供任何细节和日志,但感觉这已经是一篇很长的帖子了。非常感谢您!

【问题讨论】:

  • 你得到了什么尺寸,你的目标是什么?你确定你从模块中删除了调试信息吗?如果您不这样做,通常需要 100 兆字节。为什么不能在强大的 x86 服务器上的虚拟环境中进行简单的模糊测试?
  • 我非常接近 ~34 MiB,限制为 32 MiB。我没有从模块中删除调试信息,因为当我对它们进行模糊测试并检测崩溃或其他问题时,我想要有用的堆栈跟踪等的调试信息。如果我使用模拟器并因此为金鱼平台构建,则供应商特定的驱动程序我感兴趣的将被省略(因为相应的硬件不存在)。
  • 但我正在考虑选择性地将调试信息保留在我正在模糊测试的一些模块中,然后构建另一个内核来模糊其他模块等。可能是一个可行的解决方法,但一个干净的解决方案会更好

标签: android linux linux-kernel android-source


【解决方案1】:

我找到了适合我的解决方案。不过,这是一个很接近的电话,对于不同的情况可能还不足以减小尺寸。无论如何,它可能会帮助其他人。

我使用的是pigz,而不是默认的gzip 工具,它通过-11 开关提供了更高的压缩级别。使用-I 45 增加优化迭代次数进一步改进了它(默认为 15)。这挤出了我需要的最后一点:生成的Image.gz-dtb 比以前小了大约 2.5%。

这些是我对内核构建系统所做的更改(假设 pigz 在构建时将在您的 PATH 中):

diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index b7cf2a498c19..7dfd438e997b 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -30,7 +30,8 @@ $(obj)/Image: vmlinux FORCE
        $(call if_changed,objcopy)

 $(obj)/Image.gz: $(obj)/Image FORCE                                    
-       $(call if_changed,gzip)                  
+#      $(call if_changed,gzip)
+       $(call if_changed,pigz)

 $(obj)/Image.lz4: $(obj)/Image FORCE  
        $(call if_changed,lz4)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib                      
index c2b437eb23d5..73d4581f7531 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -272,6 +272,11 @@ quiet_cmd_gzip = GZIP    $@
 cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
        (rm -f $@ ; false)

+
+quiet_cmd_pigz = PIGZ    $@
+cmd_pigz = (cat $(filter-out FORCE,$^) | pigz -n -f -11 -I 45 > $@) || \
+       (rm -f $@ ; false)
+
 # DTC
 # ---------------------------------------------------------------------------

它闪烁和启动良好,甚至在合理的时间内启动,与我之前的不同。

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2015-01-11
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2021-07-23
    • 2017-02-06
    相关资源
    最近更新 更多