android L 开始支持arm64 cpu 。
但是通过kernel官方文档,可以看到arm64不再支持kernel压缩了。
kernel/Documentation/arm64/booting.txt
3. Decompress the kernel image
------------------------------
Requirement: OPTIONAL
The AArch64 kernel does not currently provide a decompressor and
therefore requires decompression (gzip etc.) to be performed by the boot
loader if a compressed Image target (e.g. Image.gz) is used. For
bootloaders that do not implement this requirement, the uncompressed
Image target is available instead.
翻译一下:
AArch64架构 kernel 不提供gzip等解压器(为什么arm64不支持?),如果要使用压缩的kernel image, bootloader必然支持解压功能(即android LK必然先解压kernel,然后启动)。 否则,你就只能使用未压缩的kernel image啦!!
通过看代码,确实kernel/arch/arm64/boot 目录,确实没有arm32目录kernel/arch/arm/boot/compressed下的decompressor相关代码 。
android KK 版本,仅支持arm32,且kernel image 编译时默认使用中gzip压缩,然后kernel启动时自解压。
如我之前写的另一篇blog《android系统分区大小设置的经验值》,android KK版本boot分区,都设置得比较小,一般只有20M左右。而android L版kernel image不压缩,编译出来的kernel image一般在在30M以上?
问题来了! KK版本升级到L版本,boot分区太小,导致L版本无法升级! 怎么办?
1、首先看kernel如何压缩生成Image.gz :
/kernel/arch/arm64/boot/Makefile
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/Image.gz: $(obj)/Image FORCE
$(call if_changed,gzip) // Image通过使用gzip命令压缩为文件:Image.gz
$(obj)/Image.gz-dtb: $(obj)/Image.gz $(DTB_OBJS) FORCE // dtb直接copy到Image.gz后,可见dtb没有压缩的。
$(call if_changed,cat)
2、 kernel/Android.mk 文件中根据arch64/arch32这则不同的压缩文件。arm64使用上面通过gzip压缩出来的Image.gz 。
然后 build/core/Makefile 通过mkbootimg 将 ramdisk, Image.gz, dtb 打包成 boot.img。
ifeq ($(TARGET_ARCH), arm64)
ifeq ($(APPENDED_DTB_SUPPORT), yes)
TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/$(TARGET_ARCH)/boot/Image.gz-dtb
else
TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/$(TARGET_ARCH)/boot/Image.gz
endif
else
ifeq ($(APPENDED_DTB_SUPPORT), yes)
TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/$(TARGET_ARCH)/boot/zImage-dtb
else
TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/$(TARGET_ARCH)/boot/zImage
endif
endif
3、 根据 kernel/Documentation/arm64/booting.txt描述,arch64不支持自解压,必须在lk中解压,但android default 是不支持。
不过,还好zlib是开源软件,android系统自带zlib代码在目录:external/zlib/src
我们只需将解压相关的代码移植到lk,解压Image.gz后,再启动kernel 。