Search code examples
androidkernelandroid-sourcedevice-tree

Missing Kernel DTB after creating signed Android images


I'm porting android to a display device, and have nearly completed this. The device use the Freescale/NXP i.MX6 Dual Lite Soc. The Android version used is Android 8.0.0, and the build is based on the Board Support Packages from NXP/Freescale (link below). https://www.nxp.com/support/developer-resources/software-development-tools/i.mx-developer-resources/android-os-for-i.mx-applications-processors:IMXANDROID?tab=Design_Tools_Tab

The OS builds fine, and the images (u-boot, boot.img, system.img, vendor.img) resuling from the "make" process works perfercly fine on the device. So my last step is basically to sign the images, and this is where I struggle to get stuff working.

I am following the the guide found here: https://source.android.com/devices/tech/ota/sign_builds

After completing the steps, I use the now signed images found in the "signed-img.zip" file to flash the device (using the NXP Manufacturing Tool, and not Fast Boot). However, the device now fails to boot the Kernel, giving me an error that the DTB is missing.

Hit any key to stop autoboot:  0 
boota mmc0 
kernel   @ 14008000 (8183104)
ramdisk  @ 15000000 (2036048)
## Booting Android Image at 0x12000000 ...
Kernel load addr 0x14008000 size 7992 KiB
Kernel command line: console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off vmalloc=128M androidboot.console=ttymxc0 consoleblank=0 ldo_active=on androidboot.hardware=sedevices cma=448M android.selinux=permissive android.dm_verify=disable androidboot.selinux=enforce androidboot.dm_verity=disable androidboot.storage_type=emmc loglevel=8 vt.global_cursor_default=0 buildvariant=userdebug androidboot.serialno=0b2861d4df668b47 androidboot.soc_type=imx6dl androidboot.storage_type=emmc
ERROR: Did not find a cmdline Flattened Device Tree
Could not find a valid device tree
resetting ...

I've narrowed the problem down to the very first step in the guide, where "make dist" is executed in the build directory. This produces a number of ZIP files in the "out/dist" folder, which is processed further in the following steps in the guide. I've tried flashing the device with the images produced in this step (found in the resulting "out/dist/*-img-*.zip" file), and this produces the exact same issue.

So my question is, what does really "make dist" do which cause the DTB to be missing in the "boot.img"? I would've expected it to use the already working "boot.img" found in "out/target/product//". But it instead seems to re-build this image, and in this case not include the DTB. As with so many other aspects of building Android from Source, the workings of "make dist" does not seem to be explained anywhere in the documentation.

I hope anyone with some experience in building Android from source knows something about this, because I seem to be royally stuck.

Just FYI; when I flash the "boot.img" produced after a normal "make", the output after U-boot is as follows:

Hit any key to stop autoboot:  0 
boota mmc0 
Error: blob decap job completed with errors 0x2000081A
In boota get fastboot lock status error. Set lock status
kernel   @ 14008000 (8183104)
ramdisk  @ 15000000 (2036754)
fdt      @ 14f00000 (40998)
## Booting Android Image at 0x12000000 ...
Kernel load addr 0x14008000 size 7992 KiB
Kernel command line: console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off vmalloc=128M androidboot.console=ttymxc0 consoleblank=0 ldo_active=on androidboot.hardware=sedevices cma=448M android.selinux=permissive android.dm_verify=disable androidboot.selinux=enforce androidboot.dm_verity=disable androidboot.storage_type=emmc loglevel=8 vt.global_cursor_default=0 buildvariant=userdebug androidboot.serialno=0b2861d4df668b47 androidboot.soc_type=imx6dl androidboot.storage_type=emmc
## Flattened Device Tree blob at 14f00000
   Booting using the fdt blob at 0x14f00000
   Loading Kernel Image ... OK
   Using Device Tree in place at 14f00000, end 14f0d025
switch to ldo_bypass mode!

Starting kernel ...

Solution

  • It seem NXP/Freescale have modified the Build Scripts in their AOSP Board Support Package, and broken the DTB inclusion in the process. It may seem like they where happy when the output from the standard "make" process worked on their Dev Board, and never bothered checking if it was possible to create working signed Release images with it.

    The mechanism to include a DTB in the dist package was in place (specifying the location of the DTB in BOARD_KERNEL_DTS), and was also used for their "make otapackage" target. However, that target only generates an unsigned (or signed with dev keys) OTA package, which can not be used with the signing scripts.

    In order to make it work as it should, I had to make a small change in the main Makefile which specifies the location of the DTB defined in the BoardConfig.mk. The change was simple enough to make, but the hard part was figuring out where the problem was and how it was intended to work in the first place.

    The following patch in "build/make/" fixes the issue, as long as a BoardConfig.mk ONLY specifies one DTB (which at least suits my needs):

    diff --git a/core/Makefile b/core/Makefile
    index a650565a1..92f3025a9 100644
    --- a/core/Makefile
    +++ b/core/Makefile
    @@ -621,6 +621,19 @@ ifdef INTERNAL_KERNEL_CMDLINE
     INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)"
     endif
    
    +# NOTE! This script has a defect which cause the kernel DTB to be left out when ever 'make dist'
    +#       is executed. The following addition "fixes" this by adding the first dtb specified in the 
    +#       BoardConfig.mk file. (I would guess in most cases there is never more than one!)
    +ifdef dist_goal
    +ifndef BOARD_KERNEL_DTS
    +ifdef TARGET_BOARD_DTS_CONFIG
    +DTS_BOARD=$(word 2, $(subst :, ,$(word 1, $(TARGET_BOARD_DTS_CONFIG))))
    +BOARD_KERNEL_DTS="$(KERNEL_OUT)/$(DTS_BOARD)"
    +$(info FIXUP: Defining BOARD_KERNEL_DTS:=[$(BOARD_KERNEL_DTS)] for BOOT packaging)
    +endif
    +endif
    +endif
    +
     INTERNAL_MKBOOTIMG_VERSION_ARGS := \
         --os_version $(PLATFORM_VERSION) \
         --os_patch_level $(PLATFORM_SECURITY_PATCH)