[gbl] Integrate GBL bootloader and inject AVB permanent attributes * Integrate GBL binary into U-Boot rodata section via assembly .incbin. * Increase bl33 executable limit to 6MB in u-boot.lds. * Dynamically set gbl_addr and bootgbl environment variables from embedded GBL symbols. * Inject Fuchsia dev permanent attributes and hash into FDT /gbl node. * Skip adding raw FDT to ZBI during EFI boot so GBL handles Devicetree handoff. * Update default boot command to boot GBL (`bootgbl`). * Fix EFI crashes by adding NULL checks and relocating initialization. * Update fastboot reboot modes and GPIO upgrade button in U-Boot environment to enter GBL fastboot mode. * Fix GBL Fastboot Transport protocol return value and error messaging. Bug: 496295142 TAG=agy CONV=236c2e4e-69e4-48b6-a8ea-8986bc68bb04 Change-Id: I55ae5d7a4631384ca281851c165b68401ee424ea Reviewed-on: https://turquoise-internal-review.googlesource.com/c/third_party/u-boot/+/1370276 Commit-Queue: Sergii Parubochyi <sergiip@google.com> Reviewed-by: David Pursell <dpursell@google.com> GitOrigin-RevId: 8d1eb218efd25a64e599334849653288c8cd06c8
diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds index 0aba708..567049e 100644 --- a/arch/arm/cpu/armv8/u-boot.lds +++ b/arch/arm/cpu/armv8/u-boot.lds
@@ -102,7 +102,7 @@ KEEP(*(.__bss_end)); } - ASSERT(_end <= 0x01200000, "bl33 image has exceeded its limit.") + ASSERT(_end <= 0x01400000, "bl33 image has exceeded its limit.") /DISCARD/ : { *(.dynsym) } /DISCARD/ : { *(.dynstr*) }
diff --git a/board/khadas/configs/kvim3.h b/board/khadas/configs/kvim3.h index 52bb651..6743209 100644 --- a/board/khadas/configs/kvim3.h +++ b/board/khadas/configs/kvim3.h
@@ -205,7 +205,7 @@ "setenv reboot_mode_android ""normal"";"\ "run storeargs;"\ "echo reboot_mode is fastboot. Entering fastboot;"\ - "fastboot;"\ + "setenv gbl_one_shot_boot_mode bootloader; run bootgbl;"\ "fi;fi;fi;fi;fi;fi;"\ "\0" \ "storeboot="\ @@ -213,7 +213,7 @@ "run storeargs;"\ "zbi_boot ${loadaddr} ${loadsize} kernel;"\ "echo failed to boot kernel. Falling back to fastboot;"\ - "fastboot;"\ + "setenv gbl_one_shot_boot_mode bootloader; run bootgbl;"\ "\0"\ "factory_reset_poweroff_protect="\ "echo wipe_data=${wipe_data}; echo wipe_cache=${wipe_cache};"\ @@ -238,7 +238,7 @@ "run recovery_from_flash;"\ "fi; \0" \ "update="\ - "fastboot; "\ + "setenv gbl_one_shot_boot_mode bootloader; run bootgbl; "\ "\0"\ "recovery_from_sdcard="\ "if fatload mmc 0 ${loadaddr} aml_autoscript; then autoscr ${loadaddr}; fi;"\ @@ -259,7 +259,7 @@ "recovery_from_flash="\ "zbi_boot ${loadaddr} ${loadsize} recovery;"\ "echo failed to boot recovery. Falling back to fastboot;"\ - "run storeargs; fastboot;"\ + "run storeargs; setenv gbl_one_shot_boot_mode bootloader; run bootgbl;"\ "\0"\ "init_display="\ "get_rebootmode;"\ @@ -365,9 +365,8 @@ "\0"\ "upgrade_key="\ "if gpio input GPIOAO_7; then "\ - "echo detect upgrade key. Enetering fastboot;"\ - "run storeargs;"\ - "run update;"\ + "echo detect upgrade key. Setting GBL fastboot mode;"\ + "setenv gbl_one_shot_boot_mode bootloader;"\ "fi;"\ "\0"\ "recovery_key="\ @@ -399,7 +398,7 @@ "run upgrade_key;"\ "run switch_bootmode;" -#define CONFIG_BOOTCOMMAND "run storeboot" +#define CONFIG_BOOTCOMMAND "run bootgbl" /* * logo image path: device/khadas/$(proj_name)/logo_img_files/
diff --git a/board/khadas/kvim3/Makefile b/board/khadas/kvim3/Makefile index ac966f5..8d8e0c5 100644 --- a/board/khadas/kvim3/Makefile +++ b/board/khadas/kvim3/Makefile
@@ -1,8 +1,10 @@ -obj-y += $(BOARD).o eth_setup.o +obj-y += $(BOARD).o eth_setup.o gbl_blob.o obj-$(CONFIG_ZIRCON_BOOT_IMAGE) += zircon.o zircon_boot.o obj-$(CONFIG_AML_LCD) += lcd.o +asflags-y := -Wa,-I$(srctree)/board/khadas/kvim3 + fuchsia_sdk=lib/fuchsia/firmware_sdk/pkg ccflags-y += \ -I$(fuchsia_sdk)/abr/include \
diff --git a/board/khadas/kvim3/atx_permanent_attributes.h b/board/khadas/kvim3/atx_permanent_attributes.h index 7f45d34..e523f9c 100644 --- a/board/khadas/kvim3/atx_permanent_attributes.h +++ b/board/khadas/kvim3/atx_permanent_attributes.h
@@ -10,7 +10,7 @@ #ifndef VIM3_PERMANENT_ATTRIBUTES_H #define VIM3_PERMANENT_ATTRIBUTES_H -const unsigned char avb_atx_permanent_attributes[] __attribute__((unused)) = { +static const unsigned char avb_atx_permanent_attributes[] __attribute__((unused)) = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xa1, 0x21, 0x50, 0x61, 0xd2, 0xa9, 0x3e, 0x6a, 0x6e, 0xa1, 0x4f, 0xaa, 0x43, 0x8b, 0xa1, 0xb9, 0x66, 0x14, 0x07, 0x8d, 0x70, 0x0c, 0x90, 0xed, 0x55, 0x2d, 0x26, 0xcf, @@ -101,4 +101,11 @@ 0xa4, 0x3d, 0xe4, 0xf3, 0xcc, 0x21, 0x85, 0xce, }; +static const unsigned char avb_atx_permanent_attributes_hash[32] __attribute__((unused)) = { + 0x6c, 0x94, 0x37, 0x75, 0xbe, 0x5c, 0x83, 0xe0, + 0xee, 0x41, 0x8f, 0x5a, 0x84, 0xfb, 0x9e, 0x1e, + 0x76, 0xf1, 0x68, 0xd9, 0x63, 0xb5, 0x02, 0xab, + 0x24, 0x6c, 0x1f, 0x5f, 0xbb, 0x01, 0x7b, 0x53 +}; + #endif \ No newline at end of file
diff --git a/board/khadas/kvim3/gbl_blob.S b/board/khadas/kvim3/gbl_blob.S new file mode 100644 index 0000000..e700070 --- /dev/null +++ b/board/khadas/kvim3/gbl_blob.S
@@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +.section .rodata.gbl, "a" +.align 4 +.global gbl_binary_start +.global gbl_binary_end + +gbl_binary_start: +.incbin "gbl.efi" +gbl_binary_end:
diff --git a/board/khadas/kvim3/kvim3.c b/board/khadas/kvim3/kvim3.c index e3a2231..d2a6865 100644 --- a/board/khadas/kvim3/kvim3.c +++ b/board/khadas/kvim3/kvim3.c
@@ -71,6 +71,8 @@ #endif #include <asm/arch/timer.h> #include <asm/saradc.h> +#include "atx_permanent_attributes.h" + DECLARE_GLOBAL_DATA_PTR; //new static eth setup @@ -754,9 +756,65 @@ } #ifdef CONFIG_BOARD_LATE_INIT +static void inject_gbl_attributes(void *fdt) +{ + /* + * Expand FDT to allow adding new nodes/properties. + * We have at least 256KB buffer (since U-Boot reads 0x40000 bytes). + * We can safely expand it by 4KB. + */ + int new_size = fdt_totalsize(fdt) + 4096; + if (new_size > SZ_256K) { + printf("U-Boot: Error: expanded DTB size %d exceeds max buffer %d\n", + new_size, SZ_256K); + return; + } + int ret = fdt_open_into(fdt, fdt, new_size); + if (ret < 0) { + printf("U-Boot: fdt_open_into failed: %d\n", ret); + return; + } + + int node = fdt_find_or_add_subnode(fdt, 0, "gbl"); + if (node < 0) { + printf("U-Boot: Failed to find/create /gbl node: %d\n", node); + return; + } + + ret = fdt_setprop(fdt, node, "avb-cert-permanent-attributes", + avb_atx_permanent_attributes, sizeof(avb_atx_permanent_attributes)); + if (ret) { + printf("U-Boot: Failed to set avb-cert-permanent-attributes: %d\n", ret); + return; + } + + ret = fdt_setprop(fdt, node, "avb-cert-permanent-attributes-hash", + avb_atx_permanent_attributes_hash, sizeof(avb_atx_permanent_attributes_hash)); + if (ret) { + printf("U-Boot: Failed to set avb-cert-permanent-attributes-hash: %d\n", ret); + } +} + +extern const uint8_t *gbl_binary_start; +extern const uint8_t *gbl_binary_end; + +static void setup_embedded_gbl_env(void) +{ + ulong addr = (ulong)&gbl_binary_start; + ulong size = (ulong)&gbl_binary_end - (ulong)&gbl_binary_start; + char buf[128]; + + sprintf(buf, "0x%lx", addr); + setenv("gbl_addr", buf); + + sprintf(buf, "bootefi 0x%lx:0x%lx ${dtb_mem_addr}", addr, size); + setenv("bootgbl", buf); +} + int board_late_init(void) { TE(__func__); + setup_embedded_gbl_env(); //update env before anyone using it run_command("get_rebootmode; echo reboot_mode=${reboot_mode}; "\ "if test ${reboot_mode} = factory_reset; then "\ @@ -794,6 +852,20 @@ } } #endif// #ifndef DTB_BIND_KERNEL + { + const char *addr_str = getenv("dtb_mem_addr"); + if (addr_str) { + ulong addr = simple_strtoul(addr_str, NULL, 16); + void *fdt = (void *)addr; + if (fdt_check_header(fdt) == 0) { + gd->fdt_blob = fdt; + char buf[32]; + sprintf(buf, "0x%lx", addr); + setenv("fdtcontroladdr", buf); + inject_gbl_attributes(fdt); + } + } + } #ifdef CONFIG_POWER_FUSB302 fusb302_sink_init();
diff --git a/board/khadas/kvim3/zircon.c b/board/khadas/kvim3/zircon.c index a144c15..8cd0e5c 100644 --- a/board/khadas/kvim3/zircon.c +++ b/board/khadas/kvim3/zircon.c
@@ -510,7 +510,7 @@ return res; } -int zircon_preboot(zbi_header_t *zbi, size_t capacity) +int zircon_preboot(zbi_header_t *zbi, size_t capacity, bool is_efi_boot) { #if 0 //Deprecated cpu topology descripiton add_zbi_item_or_log(zbi, capacity, ZBI_TYPE_CPU_CONFIG, 0, &cpu_config, @@ -603,6 +603,10 @@ add_cmdline_entropy(zbi, capacity); add_cpu_topology(zbi, capacity); add_eth_mac_address(zbi, capacity); - add_device_tree(zbi, capacity); + if (is_efi_boot) { + printf("U-Boot: Skipping add_device_tree for EFI boot\n"); + } else { + add_device_tree(zbi, capacity); + } return 0; }
diff --git a/board/khadas/kvim3/zircon_boot.c b/board/khadas/kvim3/zircon_boot.c index 579f8d9..7f01c04 100644 --- a/board/khadas/kvim3/zircon_boot.c +++ b/board/khadas/kvim3/zircon_boot.c
@@ -104,7 +104,7 @@ return false; } - int ret = zircon_preboot(image, capacity); + int ret = zircon_preboot(image, capacity, false); if (ret < 0) { printf("zircon_preboot failed\n"); return false; @@ -276,7 +276,7 @@ if (result != ZBI_RESULT_OK) { return -1; } - return add_zbi_items(&zb_ops, buffer, capacity, NULL) ? 0 : -1; + return zircon_preboot(buffer, capacity, true) == 0 ? 0 : -1; } int do_zbi_boot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
diff --git a/drivers/mmc/aml_sd_emmc.c b/drivers/mmc/aml_sd_emmc.c index 27a5dde..f246922 100644 --- a/drivers/mmc/aml_sd_emmc.c +++ b/drivers/mmc/aml_sd_emmc.c
@@ -1160,6 +1160,7 @@ } bool is_aml_sd_mmc(struct mmc *mmc) { + if (!mmc) return false; return mmc->cfg->ops == &aml_sd_emmc_ops; }
diff --git a/fuchsia_build.py b/fuchsia_build.py index ae9ec3c..b5456ed 100755 --- a/fuchsia_build.py +++ b/fuchsia_build.py
@@ -23,8 +23,10 @@ _CIPD_DEPS_DIR = _MY_DIR / "cipd_deps" +_GBL_CIPD_VERSION = "latest" -def build(): + +def build(gbl_path: Optional[Path] = None): """Builds the CIPD package.""" # Pass compilers for u-boot host tools build @@ -41,6 +43,8 @@ HOSTLD=host_clang / "bin" / "lld", CROSS_COMPILE="aarch64-elf-", ) + if gbl_path: + build_env["VIM3_GBL_PATH"] = str(gbl_path) subprocess.run( _BUILD_SCRIPT_TARGET, @@ -62,6 +66,10 @@ action="store_true", help="Clear CIPD dependencies dir before start", ) + parser.add_argument( + "--gbl-path", + help="Path to local GBL efi binary. If provided, CIPD GBL is not used.", + ) return parser.parse_args() @@ -99,7 +107,7 @@ shutil.rmtree(_CIPD_DEPS_DIR, ignore_errors=True) -def fuchsia_build(cipd, clean_cipd): +def fuchsia_build(cipd, clean_cipd, gbl_path=None): if clean_cipd: cipd_dep_dir_clean() @@ -143,9 +151,48 @@ "", ), ] + + resolved_gbl_path = None + if gbl_path: + resolved_gbl_path = Path(gbl_path).resolve() + if not resolved_gbl_path.exists(): + sys.exit(f"ERROR: Provided --gbl-path '{gbl_path}' does not exist.") + + if not resolved_gbl_path: + list_of_packages.append(( + "gbl", + "fuchsia/third_party/android/gbl/mainline", + _GBL_CIPD_VERSION, + "", + )) + ensure_deps(cipd, list_of_packages) - build() + if not resolved_gbl_path: + cipd_gbl_path = _CIPD_DEPS_DIR / "gbl" / "gbl_aarch64_dev.efi" + if cipd_gbl_path.exists(): + resolved_gbl_path = cipd_gbl_path + print(f"Using GBL from CIPD: {resolved_gbl_path}") + else: + sys.exit("ERROR: GBL CIPD package downloaded but gbl_aarch64_dev.efi not found.") + else: + print(f"Using local GBL: {resolved_gbl_path}") + + target_gbl = _MY_DIR / "board" / "khadas" / "kvim3" / "gbl.efi" + if resolved_gbl_path != target_gbl: + shutil.copyfile(resolved_gbl_path, target_gbl) + + build(gbl_path=resolved_gbl_path) + + uboot_bin = _MY_DIR / "build" / "u-boot.bin.unsigned" + if uboot_bin.exists(): + size = uboot_bin.stat().st_size + max_size = 4 * 1024 * 1024 + if size > max_size: + sys.exit( + f"ERROR: Final bootloader image size ({size} bytes / {size / (1024 * 1024):.2f} MiB) " + f"exceeds 4 MiB eMMC boot partition limit." + ) def _main() -> int: @@ -155,6 +202,7 @@ fuchsia_build( cipd=args.cipd, clean_cipd=args.clean_cipd, + gbl_path=args.gbl_path, )
diff --git a/include/zircon.h b/include/zircon.h index fc63a30..966d852 100644 --- a/include/zircon.h +++ b/include/zircon.h
@@ -13,7 +13,7 @@ #include <libzbi/zbi.h> /* called before booting to allow board specific additions to the bootdata */ -int zircon_preboot(zbi_header_t *zbi, size_t capacity); +int zircon_preboot(zbi_header_t *zbi, size_t capacity, bool is_efi_boot); AvbIOResult read_rollback_index(AvbOps *ops, size_t rollback_index_location, uint64_t *out_rollback_index);
diff --git a/lib/efi_loader/efi_android_boot.c b/lib/efi_loader/efi_android_boot.c index 6e994cc..c19d134 100644 --- a/lib/efi_loader/efi_android_boot.c +++ b/lib/efi_loader/efi_android_boot.c
@@ -65,6 +65,7 @@ } *max_packet_size = fastboot_func->in_ep->maxpacket; + android_boot.max_out_req_length = fastboot_func->out_req->length; return EFI_EXIT(EFI_SUCCESS); } @@ -251,6 +252,5 @@ return ret; } - android_boot.max_out_req_length = fastboot_func->out_req->length; return EFI_SUCCESS; }
diff --git a/lib/efi_loader/gbl_efi_fastboot_transport.c b/lib/efi_loader/gbl_efi_fastboot_transport.c index 266bd6c..81016cb 100644 --- a/lib/efi_loader/gbl_efi_fastboot_transport.c +++ b/lib/efi_loader/gbl_efi_fastboot_transport.c
@@ -235,6 +235,6 @@ { efi_status_t ret = efi_add_protocol(efi_root, &guid, (void *)&protocol); if (ret != EFI_SUCCESS) - printf("Cannot install EFI_ANDROID_BOOT_PROTOCOL\n"); - return EFI_SUCCESS; + printf("Cannot install GBL_EFI_FASTBOOT_TRANSPORT_PROTOCOL\n"); + return ret; }