How to select a devicetree overlay (*.dtbo) dynamically in runtime?

Which system do you use? Android, Ubuntu, OOWOW or others?


Which version of system do you use? Please provide the version of the system here:


Please describe your issue below:

I want to select the appropriate devicetree overlay (*.dtbo) file in runtime in u-boot based on detected hardware in u-boot (e.g. if i2c EEPROM can be probed or not). Currently the overlay selection is done build time using device/khadas/kvim4/ += androidboot.dtbo_idx=0

What works:

  1. Minor patch in device/khadas/common/kernelbuild/ under "===build dtbo===" section to include all overlay files in the dtbo.img. I can verify in u-boot logs that multiple overlays now exist (see below)

  2. Add u-boot command in bootloader/uboot/board/khadas/configs/kvim4.h:CONFIG_PREBOOT that detects hardware and sets androidboot.dtbo_idx=[0|1] with setenv.

What does not work:

  1. bootloader/uboot/common/bootm.c:do_fdt_overlay() does not pickup the androidboot.dtbo_idx I set in runtime with the command in CONFIG_PREBOOT above. It only considers the build-time value of androidboot.dtbo_idx=0. I can see that the kernel command line is does not contains the full bootargs created during u-boot booting, the cmdline is different. Is this due to Android Verified Boot (avb)?

How do I change androidboot.dtbo_idx in runtime and make it available in do_fdt_overlay()?

avb2: 1
active_slot is _a
ab_suffix is _a
AVB2 verifying with fip key
invalid magic for rsapub
cannot find fipkey
AVB2 cannot find fip key
AVB2 verify with default kpub:520, vbmeta kpub:520
_verify_dtb_checksum()-2815: calc 61f5af3f, store 61f5af3f
_verify_dtb_checksum()-2815: calc 61f5af3f, store 61f5af3f
dtb_read()-3030: total valid 2
update_old_dtb()-3011: do nothing
_get_part_index_by_name()-175: do not find match in table system_a
_get_part_index_by_name()-175: do not find match in table system_a
avb verification: locked = 1, result = 0
avb2: 1
## Booting Android Image at 0x03080000 ...
Kernel command line: androidboot.dynamic_partitions=true androidboot.dtbo_idx=0 androidboot.boot_devices=soc/fe08c000.mmc useg
load dtb from 0x1000000 ......
      Amlogic Multi-DTB tool
      Single DTB detected
env select addr: 0x0x1000000
## Flattened Device Tree blob at 01000000
   Booting using the fdt blob at 0x1000000
active_slot is _a
Start read dtbo_a partition datas!
find 2 dtbos
dtbos to be applied: 0
Apply dtbo 0
   Uncompressing Kernel Image ... OK
   Loading Ramdisk to 3e94a000, end 3f7ff464 ... OK
   Loading Device Tree to 000000001ffe0000, end 000000001ffffacf ... OK

Hello @xavier

@william.lin will help you then.

1 Like

I can confirm that the device tree overlay mechanism essentially works as implemented in the SDK sources, I had previously made a typo.

To make it functional (as in: it selects different overlays depending on runtime detection of hardware), the following changes are needed:

  1. Add all the different overlay files in common/arch/arm64/boot/dts/amlogic/

  2. Edit device/khadas/common/kernelbuild/ under "===build dtbo===" section to include all overlay files in the dtbo.img. Currently only the file defined by device/khadas/kvim4/build.config.meson.arm64.trunk:DTBO_DEVICETREE is included in the build.

  3. Create and execute a u-boot command/script during the CONFIG_PREBOOT stage that detects the hardware and selects the correct device tree overlay index by calling setenv androidboot.dtbo_idx <selected index>;

  4. Even if device/khadas/kvim4/ += androidboot.dtbo_idx=0 is defined at build time the runtime variable will take precedence based on the code in bootloader/uboot/common/image-android.c:save_dtbo_idx()