[U-Boot] [PATCH 0/7] am57xx: Implement Android 10 boot flow

Android 10 brings a lot of new requirements for bootloaders: [1]. This patch series attempts to implement such a boot process on BeagleBoard X15 platform. Some common code is added too, which can be reused later for other platforms.
[1] https://source.android.com/devices/bootloader
Sam Protsenko (7): image: android: Add functions for handling dtb field image: android: Add routine to get dtbo params cmd: bootimg: Add bootimg command configs: am57xx_evm: Enable Android commands env: ti: boot: Respect slot_suffix in AVB commands env: ti: boot: Boot Android with dynamic partitions arm: ti: boot: Use correct dtb and dtbo on Android boot
cmd/Kconfig | 8 + cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++ common/Makefile | 2 +- common/image-android.c | 245 ++++++++++++++++++++++++++++ configs/am57xx_evm_defconfig | 8 +- configs/am57xx_hs_evm_defconfig | 6 + configs/am57xx_hs_evm_usb_defconfig | 8 +- include/configs/ti_armv7_common.h | 7 + include/environment/ti/boot.h | 145 ++++++++-------- include/image.h | 7 + 11 files changed, 546 insertions(+), 68 deletions(-) create mode 100644 cmd/bootimg.c

Android Boot Image v2 adds "DTB" payload (and corresponding field in the image header). Provide functions for its handling:
- android_image_get_dtb_by_index(): Obtain DTB file from "DTB" part of boot image, by file index - android_image_print_dtb_contents(): Iterate over all DTB files in "DTB" part of boot image and print those files info
"DTB" payload might be in one of the following formats: 1. concatenated DTB files 2. Android DTBO format
The latter requires "android-image-dt.c" functionality, so this commit selects that file for building for CONFIG_ANDROID_BOOT_IMAGE option.
Right now this new functionality isn't used, but it can be used further. As it's required to apply some specific dtbo file(s) from "dtbo" partition, we can't automate this process inside of "bootm" command. But we can do next: - come up with some new command like "bootimg" to extract dtb file from boot image (using functions from this patch) - extract desired dtbo files from "dtbo" partition using "dtimg" command - merge dtbo files into dtb file using "fdt apply" command - pass resulting dtb file into bootm command in order to boot the Android kernel with Android ramdisk from boot image
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- common/Makefile | 2 +- common/image-android.c | 191 +++++++++++++++++++++++++++++++++++++++++ include/image.h | 5 ++ 3 files changed, 197 insertions(+), 1 deletion(-)
diff --git a/common/Makefile b/common/Makefile index 302d8beaf3..7e5f5058b3 100644 --- a/common/Makefile +++ b/common/Makefile @@ -108,7 +108,7 @@ endif
obj-y += image.o obj-$(CONFIG_ANDROID_AB) += android_ab.o -obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o +obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o diff --git a/common/image-android.c b/common/image-android.c index 3564a64221..63e41ea5f1 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -6,6 +6,7 @@ #include <common.h> #include <env.h> #include <image.h> +#include <image-android-dt.h> #include <android_image.h> #include <malloc.h> #include <errno.h> @@ -195,6 +196,108 @@ int android_image_get_second(const struct andr_img_hdr *hdr, return 0; }
+/** + * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image. + * @hdr: Boot image header address + * @addr: Will contain the address of DTB area in boot image + * + * Return: true on success or false on fail. + */ +static bool android_image_get_dtb_img_addr(const struct andr_img_hdr *hdr, + ulong *addr) +{ + ulong dtb_img_addr; + + if (android_image_check_header(hdr)) { + printf("Error: Boot Image header is incorrect\n"); + return false; + } + + if (hdr->header_version < 2) { + printf("Error: header_version must be >= 2 to get dtb\n"); + return false; + } + + if (hdr->dtb_size == 0) { + printf("Error: dtb_size is 0\n"); + return false; + } + + /* Calculate the address of DTB area in boot image */ + dtb_img_addr = (ulong)hdr; + dtb_img_addr += hdr->page_size; + dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size); + dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size); + dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size); + dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); + + if (addr) + *addr = dtb_img_addr; + + return true; +} + +/** + * android_image_get_dtb_by_index() - Get address and size of file in DTB area. + * @hdr: Boot image header address + * @index: Index of desired DTB in DTB area (starting from 0) + * @addr: If not NULL, will contain address to specified DTB + * @size: If not NULL, will contain size of specified DTB + * + * Get the address and size of DTB file by its index in DTB area of Android + * Boot Image in RAM. + * + * Return: true on success or false on error. + */ +bool android_image_get_dtb_by_index(const struct andr_img_hdr *hdr, u32 index, + ulong *addr, u32 *size) +{ + bool res; + ulong dtb_img_addr; /* address of DTB part in boot image */ + ulong dtb_addr; /* address of DTB file with specified index */ + u32 i; /* index iterator */ + + res = android_image_get_dtb_img_addr(hdr, &dtb_img_addr); + if (!res) + return false; + + /* Check if DTB area of boot image is in DTBO format */ + if (android_dt_check_header((ulong)dtb_img_addr)) { + return android_dt_get_fdt_by_index(dtb_img_addr, index, addr, + size); + } + + /* Find out the address of DTB with specified index in concat blobs */ + i = 0; + dtb_addr = dtb_img_addr; + while (dtb_addr < dtb_img_addr + hdr->dtb_size) { + const struct fdt_header *fdt; + u32 dtb_size; + + fdt = (const struct fdt_header *)dtb_addr; + if (fdt_check_header(fdt) != 0) { + printf("Error: Invalid FDT header for index %u\n", i); + return false; + } + + dtb_size = fdt_totalsize(fdt); + + if (i == index) { + if (size) + *size = dtb_size; + if (addr) + *addr = dtb_addr; + return true; + } + + dtb_addr += dtb_size; + ++i; + } + + printf("Error: Index is out of bounds (%u/%u)\n", index, i); + return false; +} + #if !defined(CONFIG_SPL_BUILD) /** * android_print_contents - prints out the contents of the Android format image @@ -246,4 +349,92 @@ void android_print_contents(const struct andr_img_hdr *hdr) printf("%sdtb addr: %llx\n", p, hdr->dtb_addr); } } + +static bool android_image_print_dtb_info(const struct fdt_header *fdt, + u32 index) +{ + int root_node_off; + u32 fdt_size; + const char *model; + const char *compatible; + + root_node_off = fdt_path_offset(fdt, "/"); + if (root_node_off < 0) { + printf("Error: Root node not found\n"); + return false; + } + + fdt_size = fdt_totalsize(fdt); + compatible = fdt_getprop(fdt, root_node_off, "compatible", + NULL); + model = fdt_getprop(fdt, root_node_off, "model", NULL); + + printf(" - DTB #%u:\n", index); + printf(" (DTB)size = %d\n", fdt_size); + printf(" (DTB)model = %s\n", model ? model : "(unknown)"); + printf(" (DTB)compatible = %s\n", + compatible ? compatible : "(unknown)"); + + return true; +} + +/** + * android_image_print_dtb_contents() - Print info for DTB files in DTB area. + * @hdr: Boot image header address + * + * DTB payload in Android Boot Image v2+ can be in one of following formats: + * 1. Concatenated DTB files + * 2. Android DTBO format (see CONFIG_CMD_DTIMG for details) + * + * This function does next: + * 1. Prints out the format used in DTB area + * 2. Iterates over all DTB files in DTB area and prints out the info for + * each file. + * + * Return: true on success or false on error. + */ +bool android_image_print_dtb_contents(const struct andr_img_hdr *hdr) +{ + bool res; + ulong dtb_img_addr; /* address of DTB part in boot image */ + ulong dtb_addr; /* address of DTB file with specified index */ + u32 i; /* index iterator */ + + res = android_image_get_dtb_img_addr(hdr, &dtb_img_addr); + if (!res) + return false; + + /* Check if DTB area of boot image is in DTBO format */ + if (android_dt_check_header((ulong)dtb_img_addr)) { + printf("## DTB area contents (DTBO format):\n"); + android_dt_print_contents(dtb_img_addr); + return true; + } + + printf("## DTB area contents (concat format):\n"); + + /* Iterate over concatenated DTB files */ + i = 0; + dtb_addr = dtb_img_addr; + while (dtb_addr < dtb_img_addr + hdr->dtb_size) { + const struct fdt_header *fdt; + u32 dtb_size; + + fdt = (const struct fdt_header *)dtb_addr; + if (fdt_check_header(fdt) != 0) { + printf("Error: Invalid FDT header for index %u\n", i); + return false; + } + + res = android_image_print_dtb_info(fdt, i); + if (!res) + return false; + + dtb_size = fdt_totalsize(fdt); + dtb_addr += dtb_size; + ++i; + } + + return true; +} #endif diff --git a/include/image.h b/include/image.h index c1065c06f9..08eda41961 100644 --- a/include/image.h +++ b/include/image.h @@ -1333,10 +1333,15 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr, ulong *rd_data, ulong *rd_len); int android_image_get_second(const struct andr_img_hdr *hdr, ulong *second_data, ulong *second_len); +bool android_image_get_dtb_by_index(const struct andr_img_hdr *hdr, u32 index, + ulong *addr, u32 *size); ulong android_image_get_end(const struct andr_img_hdr *hdr); ulong android_image_get_kload(const struct andr_img_hdr *hdr); ulong android_image_get_kcomp(const struct andr_img_hdr *hdr); void android_print_contents(const struct andr_img_hdr *hdr); +#if !defined(CONFIG_SPL_BUILD) +bool android_image_print_dtb_contents(const struct andr_img_hdr *hdr); +#endif
#endif /* CONFIG_ANDROID_BOOT_IMAGE */

Hi Sam,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
Android Boot Image v2 adds "DTB" payload (and corresponding field in the image header). Provide functions for its handling:
- android_image_get_dtb_by_index(): Obtain DTB file from "DTB" part of boot image, by file index
- android_image_print_dtb_contents(): Iterate over all DTB files in "DTB" part of boot image and print those files info
"DTB" payload might be in one of the following formats:
- concatenated DTB files
- Android DTBO format
The latter requires "android-image-dt.c" functionality, so this commit selects that file for building for CONFIG_ANDROID_BOOT_IMAGE option.
Right now this new functionality isn't used, but it can be used further. As it's required to apply some specific dtbo file(s) from "dtbo" partition, we can't automate this process inside of "bootm" command. But we can do next:
- come up with some new command like "bootimg" to extract dtb file from boot image (using functions from this patch)
- extract desired dtbo files from "dtbo" partition using "dtimg" command
- merge dtbo files into dtb file using "fdt apply" command
- pass resulting dtb file into bootm command in order to boot the Android kernel with Android ramdisk from boot image
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
common/Makefile | 2 +- common/image-android.c | 191 +++++++++++++++++++++++++++++++++++++++++ include/image.h | 5 ++ 3 files changed, 197 insertions(+), 1 deletion(-)
Please rememeber to add tests for new functionality.
Regards, Simon

Hi Simon,
On Fri, Sep 20, 2019 at 8:45 PM Simon Glass sjg@chromium.org wrote:
Hi Sam,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
Android Boot Image v2 adds "DTB" payload (and corresponding field in the image header). Provide functions for its handling:
- android_image_get_dtb_by_index(): Obtain DTB file from "DTB" part of boot image, by file index
- android_image_print_dtb_contents(): Iterate over all DTB files in "DTB" part of boot image and print those files info
"DTB" payload might be in one of the following formats:
- concatenated DTB files
- Android DTBO format
The latter requires "android-image-dt.c" functionality, so this commit selects that file for building for CONFIG_ANDROID_BOOT_IMAGE option.
Right now this new functionality isn't used, but it can be used further. As it's required to apply some specific dtbo file(s) from "dtbo" partition, we can't automate this process inside of "bootm" command. But we can do next:
- come up with some new command like "bootimg" to extract dtb file from boot image (using functions from this patch)
- extract desired dtbo files from "dtbo" partition using "dtimg" command
- merge dtbo files into dtb file using "fdt apply" command
- pass resulting dtb file into bootm command in order to boot the Android kernel with Android ramdisk from boot image
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
common/Makefile | 2 +- common/image-android.c | 191 +++++++++++++++++++++++++++++++++++++++++ include/image.h | 5 ++ 3 files changed, 197 insertions(+), 1 deletion(-)
Please rememeber to add tests for new functionality.
Will send v2 with added unit test soon, thanks!
Regards, Simon

Android Boot Image v1 adds "Recovery DTB" field in image header and associate payload in boot image itself [1]. Payload should be in Android DTB/DTBO format [2]. That "Recovery DTB" area should be only populated for non-A/B devices, and only in recovery image.
Add function to get an address and size of that payload. That function can be further used e.g. in 'bootimg' command to provide the user a way to get the address of recovery dtbo from U-Boot shell, which can be further parsed using 'dtimg' command.
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- common/image-android.c | 54 ++++++++++++++++++++++++++++++++++++++++++ include/image.h | 2 ++ 2 files changed, 56 insertions(+)
diff --git a/common/image-android.c b/common/image-android.c index 63e41ea5f1..5ecd75dcfc 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -196,6 +196,60 @@ int android_image_get_second(const struct andr_img_hdr *hdr, return 0; }
+/** + * android_image_get_dtbo() - Get address and size of recovery DTBO image. + * @hdr: Boot image header address + * @addr: If not NULL, will contain address of recovery DTBO image + * @size: If not NULL, will contain size of recovery DTBO image + * + * Get the address and size of DTBO image in "Recovery DTBO" area of Android + * Boot Image in RAM. The format of this image is Android DTBO (see + * corresponding "DTB/DTBO Partitions" AOSP documentation for details). Once + * the address is obtained from this function, one can use 'dtimg' U-Boot + * command or android_dt_*() functions to extract desired DTBO file. + * + * This DTBO (included in boot image) is only needed for non-A/B devices, and it + * only can be found in recovery image. On A/B devices we can always rely on + * "dtbo" partition. See "Including DTBO in Recovery for Non-A/B Devices" in + * AOSP documentation for details. + * + * Return: true on success or false on error. + */ +bool android_image_get_dtbo(const struct andr_img_hdr *hdr, ulong *addr, + u32 *size) +{ + ulong dtbo_img_addr; + + if (android_image_check_header(hdr)) { + printf("Error: Boot Image header is incorrect\n"); + return false; + } + + if (hdr->header_version < 1) { + printf("Error: header_version must be >= 1 to get dtbo\n"); + return false; + } + + if (hdr->recovery_dtbo_size == 0) { + printf("Error: recovery_dtbo_size is 0\n"); + return false; + } + + /* Calculate the address of DTB area in boot image */ + dtbo_img_addr = (ulong)hdr; + dtbo_img_addr += hdr->page_size; + dtbo_img_addr += ALIGN(hdr->kernel_size, hdr->page_size); + dtbo_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size); + dtbo_img_addr += ALIGN(hdr->second_size, hdr->page_size); + + if (addr) + *addr = dtbo_img_addr; + if (size) + *size = hdr->recovery_dtbo_size; + + return true; +} + /** * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image. * @hdr: Boot image header address diff --git a/include/image.h b/include/image.h index 08eda41961..c8a3088acb 100644 --- a/include/image.h +++ b/include/image.h @@ -1333,6 +1333,8 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr, ulong *rd_data, ulong *rd_len); int android_image_get_second(const struct andr_img_hdr *hdr, ulong *second_data, ulong *second_len); +bool android_image_get_dtbo(const struct andr_img_hdr *hdr, ulong *addr, + u32 *size); bool android_image_get_dtb_by_index(const struct andr_img_hdr *hdr, u32 index, ulong *addr, u32 *size); ulong android_image_get_end(const struct andr_img_hdr *hdr);

This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android.
Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details).
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 cmd/bootimg.c
diff --git a/cmd/Kconfig b/cmd/Kconfig index 98647f58b7..37f3003c2b 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -305,6 +305,14 @@ config CMD_DTIMG files should be merged in one dtb further, which needs to be passed to the kernel, as part of a boot process.
+config CMD_BOOTIMG + bool "bootimg" + depends on ANDROID_BOOT_IMAGE + help + Android Boot Image manipulation commands. Allows one to extract + images contained in boot.img, like kernel, ramdisk, dtb, etc, and + obtain corresponding meta-information from boot.img. + config CMD_ELF bool "bootelf, bootvx" default y diff --git a/cmd/Makefile b/cmd/Makefile index ac843b4b16..bf15e38f41 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -48,6 +48,7 @@ ifdef CONFIG_POST obj-$(CONFIG_CMD_DIAG) += diag.o endif obj-$(CONFIG_CMD_DTIMG) += dtimg.o +obj-$(CONFIG_CMD_BOOTIMG) += bootimg.o obj-$(CONFIG_CMD_ECHO) += echo.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o diff --git a/cmd/bootimg.c b/cmd/bootimg.c new file mode 100644 index 0000000000..4ef405f99a --- /dev/null +++ b/cmd/bootimg.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 Linaro Ltd. + * Sam Protsenko semen.protsenko@linaro.org + */ + +#include <android_image.h> +#include <common.h> + +static int do_bootimg_ver(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + char buf[65]; + + if (argc != 2) + return CMD_RET_USAGE; + + hdr = (const struct andr_img_hdr *)load_addr; + if (android_image_check_header(hdr)) { + printf("Error: Boot Image header is incorrect\n"); + return CMD_RET_FAILURE; + } + + snprintf(buf, sizeof(buf), "%u", hdr->header_version); + env_set(argv[1], buf); + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_get_dtbo(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + char buf[65]; + ulong addr; + u32 size; + + if (argc < 2 || argc > 3) + return CMD_RET_USAGE; + + hdr = (const struct andr_img_hdr *)load_addr; + if (!android_image_get_dtbo(hdr, &addr, &size)) + return CMD_RET_FAILURE; + + snprintf(buf, sizeof(buf), "%lx", addr); + env_set(argv[1], buf); + + if (argc == 3) { + snprintf(buf, sizeof(buf), "%x", size); + env_set(argv[2], buf); + } + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_dtb_dump(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + + if (argc != 1) + return CMD_RET_USAGE; + + hdr = (const struct andr_img_hdr *)load_addr; + if (android_image_print_dtb_contents(hdr)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_dtb_load_addr(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + char buf[65]; + + if (argc != 2) + return CMD_RET_USAGE; + + hdr = (const struct andr_img_hdr *)load_addr; + if (android_image_check_header(hdr)) { + printf("Error: Boot Image header is incorrect\n"); + return CMD_RET_FAILURE; + } + + if (hdr->header_version < 2) { + printf("Error: header_version must be >= 2 for this\n"); + return CMD_RET_FAILURE; + } + + snprintf(buf, sizeof(buf), "%lx", (ulong)hdr->dtb_addr); + env_set(argv[1], buf); + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_get_dtb_file(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + char *endp; + char buf[65]; + u32 index; + ulong addr; + u32 size; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + index = simple_strtoul(argv[1], &endp, 0); + if (*endp != '\0') { + printf("Error: Wrong index\n"); + return CMD_RET_FAILURE; + } + + hdr = (const struct andr_img_hdr *)load_addr; + if (!android_image_get_dtb_by_index(hdr, index, &addr, &size)) + return CMD_RET_FAILURE; + + snprintf(buf, sizeof(buf), "%lx", addr); + env_set(argv[2], buf); + + if (argc == 4) { + snprintf(buf, sizeof(buf), "%x", size); + env_set(argv[3], buf); + } + + return CMD_RET_SUCCESS; +} + +static cmd_tbl_t cmd_bootimg_sub[] = { + U_BOOT_CMD_MKENT(ver, 2, 1, do_bootimg_ver, "", ""), + U_BOOT_CMD_MKENT(get_dtbo, 3, 1, do_bootimg_get_dtbo, "", ""), + U_BOOT_CMD_MKENT(dtb_dump, 1, 1, do_bootimg_dtb_dump, "", ""), + U_BOOT_CMD_MKENT(dtb_load_addr, 2, 1, do_bootimg_dtb_load_addr, "", ""), + U_BOOT_CMD_MKENT(get_dtb_file, 4, 1, do_bootimg_get_dtb_file, "", ""), +}; + +static int do_bootimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *cp; + + cp = find_cmd_tbl(argv[1], cmd_bootimg_sub, + ARRAY_SIZE(cmd_bootimg_sub)); + + /* Strip off leading 'bootimg' command argument */ + argc--; + argv++; + + if (!cp || argc > cp->maxargs) + return CMD_RET_USAGE; + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) + return CMD_RET_SUCCESS; + + return cp->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, + "manipulate Android Boot Image (must reside in $loadaddr)", + "ver <varname>\n" + " - get header version\n" + "bootimg get_dtbo <addr_var> [size_var]\n" + " - get address and size (hex) of recovery DTBO area in the image\n" + " <addr_var>: variable name to contain DTBO area address\n" + " [size_var]: variable name to contain DTBO area size\n" + "bootimg dtb_dump\n" + " - print info for all files in DTB area\n" + "bootimg dtb_load_addr <varname>\n" + " - get load address (hex) of DTB\n" + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" + " - get address and size (hex) of DTB file in the image\n" + " <index>: index of desired DTB file in DTB area\n" + " <addr_var>: variable name to contain DTB file address\n" + " [size_var]: variable name to contain DTB file size\n" +);

Hi,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android.
Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details).
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 cmd/bootimg.c
Shouldn't this be a subcommand of avb?
Regards, Simon

Hi Simon,
On Fri, Sep 20, 2019 at 8:45 PM Simon Glass sjg@chromium.org wrote:
Hi,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android.
Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details).
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 cmd/bootimg.c
Shouldn't this be a subcommand of avb?
I think there is some misunderstanding here, as avb is used only for signature verification/roll-back protection, other aspects of booting Android (parsing android boot image) are handled by other commands (for instance, bootm).
Howewer, I think (IMHO) that `bootimg` isn't a good choice for the command name , which major functionality is manipulating dtb/dtbos.
Regards, Simon

Hi Igor,
On Mon, Sep 23, 2019 at 11:36 PM Igor Opaniuk igor.opaniuk@gmail.com wrote:
Hi Simon,
On Fri, Sep 20, 2019 at 8:45 PM Simon Glass sjg@chromium.org wrote:
Hi,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android.
Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details).
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 cmd/bootimg.c
Shouldn't this be a subcommand of avb?
I think there is some misunderstanding here, as avb is used only for signature verification/roll-back protection, other aspects of booting Android (parsing android boot image) are handled by other commands (for instance, bootm).
Howewer, I think (IMHO) that `bootimg` isn't a good choice for the command name , which major functionality is manipulating dtb/dtbos.
Actually, 'bootimg' manipulates only Android boot image, but new Android Boot Image v2 happen to have DTB field. For DTBO files in Android we already have 'dtimg' command.
Simon,
This command is not connected with AVB. It's only needed to obtain Android Boot Image payloads. We can't integrate its functionality in 'bootm' command, because we would need to merge some DTBO files (from 'dtbo' partition) into DTB file obtained from boot image. And bootm command can't possibly know which DTBO files vendor would like to use (e.g. different DTBOs for different boards). That's why I came up with 'bootimg' command.
Actually I think that we should think about implementing 'boot_android' next. Because the boot script is becoming quite cluttered. But we should have those tiny commands anyway, as it's convenient for development and provides a more flexible way to boot Android.
I'm having presentation today at Linaro Connect, highlighting new Android boot scheme. Slides will be available at [1]. The Android boot flow becomes more and more extensive, so I think it's time to start discussion between community, Google and vendors w.r.t. this topic. One point we should bring up is the possibility to use FIT image instead of bunch of Android images. I hope this is discussable.
But for now I think we should stick to established Android boot architecture, as it was published at [2] and mandatory for new devices launching with Android 10.
Thanks!
[1] https://connect.linaro.org/resources/san19/san19-217/ [2] https://source.android.com/devices/bootloader
Regards, Simon
-- Best regards - Freundliche Grüsse - Meilleures salutations
Igor Opaniuk
mailto: igor.opaniuk@gmail.com skype: igor.opanyuk +380 (93) 836 40 67 http://ua.linkedin.com/in/iopaniuk

Hi Sam,
On Tue, 24 Sep 2019 at 11:41, Sam Protsenko semen.protsenko@linaro.org wrote:
Hi Igor,
On Mon, Sep 23, 2019 at 11:36 PM Igor Opaniuk igor.opaniuk@gmail.com wrote:
Hi Simon,
On Fri, Sep 20, 2019 at 8:45 PM Simon Glass sjg@chromium.org wrote:
Hi,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android.
Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details).
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 cmd/bootimg.c
Shouldn't this be a subcommand of avb?
I think there is some misunderstanding here, as avb is used only for signature verification/roll-back protection, other aspects of booting Android (parsing android boot image) are handled by other commands (for instance, bootm).
Howewer, I think (IMHO) that `bootimg` isn't a good choice for the command name , which major functionality is manipulating dtb/dtbos.
Actually, 'bootimg' manipulates only Android boot image, but new Android Boot Image v2 happen to have DTB field. For DTBO files in Android we already have 'dtimg' command.
Simon,
This command is not connected with AVB. It's only needed to obtain Android Boot Image payloads. We can't integrate its functionality in 'bootm' command, because we would need to merge some DTBO files (from 'dtbo' partition) into DTB file obtained from boot image. And bootm command can't possibly know which DTBO files vendor would like to use (e.g. different DTBOs for different boards). That's why I came up with 'bootimg' command.
OK, so can we say this is specific to Android. So perhaps 'boota' ?
Minor point - boom allows passing an image address rather than requiring loadaddr to be set.
Actually I think that we should think about implementing 'boot_android' next. Because the boot script is becoming quite cluttered. But we should have those tiny commands anyway, as it's convenient for development and provides a more flexible way to boot Android.
Agreed on both counts.
I'm having presentation today at Linaro Connect, highlighting new Android boot scheme. Slides will be available at [1]. The Android boot flow becomes more and more extensive, so I think it's time to start discussion between community, Google and vendors w.r.t. this topic. One point we should bring up is the possibility to use FIT image instead of bunch of Android images. I hope this is discussable.
That sounds like a good idea.
But for now I think we should stick to established Android boot architecture, as it was published at [2] and mandatory for new devices launching with Android 10.
OK. Let's make sure to add sandbox tests for new functionality too.
- SImon
Thanks!
[1] https://connect.linaro.org/resources/san19/san19-217/ [2] https://source.android.com/devices/bootloader
Regards, Simon
-- Best regards - Freundliche Grüsse - Meilleures salutations
Igor Opaniuk
mailto: igor.opaniuk@gmail.com skype: igor.opanyuk +380 (93) 836 40 67 http://ua.linkedin.com/in/iopaniuk

Hi Simon,
On Wed, Sep 25, 2019 at 10:15 PM Simon Glass sjg@chromium.org wrote:
Hi Sam,
On Tue, 24 Sep 2019 at 11:41, Sam Protsenko semen.protsenko@linaro.org wrote:
Hi Igor,
On Mon, Sep 23, 2019 at 11:36 PM Igor Opaniuk igor.opaniuk@gmail.com wrote:
Hi Simon,
On Fri, Sep 20, 2019 at 8:45 PM Simon Glass sjg@chromium.org wrote:
Hi,
On Thu, 19 Sep 2019 at 12:28, Sam Protsenko semen.protsenko@linaro.org wrote:
This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android.
Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details).
[1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org
cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/bootimg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 cmd/bootimg.c
Shouldn't this be a subcommand of avb?
I think there is some misunderstanding here, as avb is used only for signature verification/roll-back protection, other aspects of booting Android (parsing android boot image) are handled by other commands (for instance, bootm).
Howewer, I think (IMHO) that `bootimg` isn't a good choice for the command name , which major functionality is manipulating dtb/dtbos.
Actually, 'bootimg' manipulates only Android boot image, but new Android Boot Image v2 happen to have DTB field. For DTBO files in Android we already have 'dtimg' command.
Simon,
This command is not connected with AVB. It's only needed to obtain Android Boot Image payloads. We can't integrate its functionality in 'bootm' command, because we would need to merge some DTBO files (from 'dtbo' partition) into DTB file obtained from boot image. And bootm command can't possibly know which DTBO files vendor would like to use (e.g. different DTBOs for different boards). That's why I came up with 'bootimg' command.
OK, so can we say this is specific to Android. So perhaps 'boota' ?
I'd like to keep 'bootimg' name, to not confuse this command with actual boot commands. The 'bootimg' doesn't boot anything, it just provides the means to work with the image which is called "boot image".
Minor point - boom allows passing an image address rather than requiring loadaddr to be set.
Good point. I have added 'set_addr' sub-command in v2, will send it soon.
Actually I think that we should think about implementing 'boot_android' next. Because the boot script is becoming quite cluttered. But we should have those tiny commands anyway, as it's convenient for development and provides a more flexible way to boot Android.
Agreed on both counts.
I'm having presentation today at Linaro Connect, highlighting new Android boot scheme. Slides will be available at [1]. The Android boot flow becomes more and more extensive, so I think it's time to start discussion between community, Google and vendors w.r.t. this topic. One point we should bring up is the possibility to use FIT image instead of bunch of Android images. I hope this is discussable.
That sounds like a good idea.
Just in case, slides and video are available here:
https://connect.linaro.org/resources/san19/san19-217/
But for now I think we should stick to established Android boot architecture, as it was published at [2] and mandatory for new devices launching with Android 10.
OK. Let's make sure to add sandbox tests for new functionality too.
Done, will send v2 soon. Thanks!
- SImon
Thanks!
[1] https://connect.linaro.org/resources/san19/san19-217/ [2] https://source.android.com/devices/bootloader
Regards, Simon
-- Best regards - Freundliche Grüsse - Meilleures salutations
Igor Opaniuk
mailto: igor.opaniuk@gmail.com skype: igor.opanyuk +380 (93) 836 40 67 http://ua.linkedin.com/in/iopaniuk

Enable Android commands that will be needed for Android 10 boot flow implementation, for all AM57x variants. Commands enabled:
1. 'bootimg': - CONFIG_CMD_BOOTIMG=y 2. 'ab_select': - CONFIG_ANDROID_AB=y - CONFIG_CMD_AB_SELECT=y 3. 'avb': - CONFIG_LIBAVB=y - CONFIG_AVB_VERIFY=y - CONFIG_CMD_AVB=y
While at it, resync defconfig files with "make savedefconfig".
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- configs/am57xx_evm_defconfig | 8 +++++++- configs/am57xx_hs_evm_defconfig | 6 ++++++ configs/am57xx_hs_evm_usb_defconfig | 8 +++++++- 3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig index 248c302057..ee7852fd30 100644 --- a/configs/am57xx_evm_defconfig +++ b/configs/am57xx_evm_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y CONFIG_ARMV7_LPAE=y CONFIG_AHCI=y +CONFIG_SPL_TEXT_BASE=0x40300000 CONFIG_DISTRO_DEFAULTS=y CONFIG_SPL_LOAD_FIT=y CONFIG_OF_BOARD_SETUP=y @@ -20,7 +21,8 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y # CONFIG_MISC_INIT_R is not set CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y -CONFIG_SPL_TEXT_BASE=0x40300000 +CONFIG_AVB_VERIFY=y +CONFIG_ANDROID_AB=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y @@ -30,11 +32,14 @@ CONFIG_SPL_SPI_LOAD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 CONFIG_SPL_YMODEM_SUPPORT=y CONFIG_CMD_DTIMG=y +CONFIG_CMD_BOOTIMG=y CONFIG_CMD_SPL=y CONFIG_CMD_BCB=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_AB_SELECT=y # CONFIG_CMD_PMIC is not set +CONFIG_CMD_AVB=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="am572x-idk" @@ -98,3 +103,4 @@ CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" CONFIG_USB_GADGET_VENDOR_NUM=0x0451 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022 +CONFIG_LIBAVB=y diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig index 7b56df8db7..89e5094a74 100644 --- a/configs/am57xx_hs_evm_defconfig +++ b/configs/am57xx_hs_evm_defconfig @@ -26,6 +26,8 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y # CONFIG_MISC_INIT_R is not set CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_AVB_VERIFY=y +CONFIG_ANDROID_AB=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y @@ -33,10 +35,13 @@ CONFIG_SPL_DMA_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 CONFIG_CMD_DTIMG=y +CONFIG_CMD_BOOTIMG=y CONFIG_CMD_BCB=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_AB_SELECT=y # CONFIG_CMD_PMIC is not set +CONFIG_CMD_AVB=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15" @@ -96,3 +101,4 @@ CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" CONFIG_USB_GADGET_VENDOR_NUM=0x0451 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022 +CONFIG_LIBAVB=y diff --git a/configs/am57xx_hs_evm_usb_defconfig b/configs/am57xx_hs_evm_usb_defconfig index c8078e9f4e..04dc402a23 100644 --- a/configs/am57xx_hs_evm_usb_defconfig +++ b/configs/am57xx_hs_evm_usb_defconfig @@ -14,6 +14,7 @@ CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y CONFIG_ARMV7_LPAE=y +CONFIG_SPL_TEXT_BASE=0x40306D50 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_IMAGE_POST_PROCESS=y CONFIG_SPL_LOAD_FIT=y @@ -26,7 +27,8 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y # CONFIG_MISC_INIT_R is not set CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y -CONFIG_SPL_TEXT_BASE=0x40306D50 +CONFIG_AVB_VERIFY=y +CONFIG_ANDROID_AB=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y @@ -38,10 +40,13 @@ CONFIG_SPL_USB_GADGET=y CONFIG_SPL_DFU=y CONFIG_SPL_YMODEM_SUPPORT=y CONFIG_CMD_DTIMG=y +CONFIG_CMD_BOOTIMG=y CONFIG_CMD_BCB=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_AB_SELECT=y # CONFIG_CMD_PMIC is not set +CONFIG_CMD_AVB=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15" @@ -103,3 +108,4 @@ CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" CONFIG_USB_GADGET_VENDOR_NUM=0x0451 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022 +CONFIG_LIBAVB=y

Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- include/environment/ti/boot.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h index 684a744f31..da99215fbd 100644 --- a/include/environment/ti/boot.h +++ b/include/environment/ti/boot.h @@ -63,7 +63,7 @@ "else " \ "echo AVB verification failed.;" \ "exit; fi;" -#define AVB_VERIFY_CMD "avb_verify=avb init 1; avb verify;\0" +#define AVB_VERIFY_CMD "avb_verify=avb init 1; avb verify $slot_suffix;\0" #else #define AVB_VERIFY_CHECK "" #define AVB_VERIFY_CMD ""

Changes: - use boot.img instead of boot_fit.img - use .dtb from boot.img v2 - implement recovery boot - always boot ramdisk from boot.img, we can't mount system as root now, as system is a logical partition inside of super partition - don't add "skip_initramfs" to cmdline anymore - to boot into recovery, use boot image from recovery partition - prepare partition table: - A/B scheme - use 'super' partition instead of 'system' and 'vendor' - add dtbo partitions - introduce metadata partition
Not implemented: reading and applying dtbo files from dtbo partition.
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- include/environment/ti/boot.h | 105 +++++++++++++--------------------- 1 file changed, 41 insertions(+), 64 deletions(-)
diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h index da99215fbd..a7644a5874 100644 --- a/include/environment/ti/boot.h +++ b/include/environment/ti/boot.h @@ -13,28 +13,6 @@ #define CONSOLEDEV "ttyS2" #endif
-#define VBMETA_PART_SIZE (64 * 1024) - -#if defined(CONFIG_LIBAVB) -#define VBMETA_PART \ - "name=vbmeta,size=" __stringify(VBMETA_PART_SIZE) \ - ",uuid=${uuid_gpt_vbmeta};" -#else -#define VBMETA_PART "" -#endif - -#if defined(CONFIG_CMD_AB_SELECT) -#define COMMON_PARTS \ - "name=boot_a,size=20M,uuid=${uuid_gpt_boot_a};" \ - "name=boot_b,size=20M,uuid=${uuid_gpt_boot_b};" \ - "name=system_a,size=1024M,uuid=${uuid_gpt_system_a};" \ - "name=system_b,size=1024M,uuid=${uuid_gpt_system_b};" -#else -#define COMMON_PARTS \ - "name=boot,size=20M,uuid=${uuid_gpt_boot};" \ - "name=system,size=1024M,uuid=${uuid_gpt_system};" -#endif - #ifndef PARTS_DEFAULT /* Define the default GPT table for eMMC */ #define PARTS_DEFAULT \ @@ -49,10 +27,15 @@ "name=bootloader,size=2048K,uuid=${uuid_gpt_bootloader};" \ "name=uboot-env,start=2432K,size=256K,uuid=${uuid_gpt_reserved};" \ "name=misc,size=128K,uuid=${uuid_gpt_misc};" \ - "name=recovery,size=40M,uuid=${uuid_gpt_recovery};" \ - COMMON_PARTS \ - "name=vendor,size=256M,uuid=${uuid_gpt_vendor};" \ - VBMETA_PART \ + "name=boot_a,size=20M,uuid=${uuid_gpt_boot_a};" \ + "name=boot_b,size=20M,uuid=${uuid_gpt_boot_b};" \ + "name=dtbo_a,size=8M,uuid=${uuid_gpt_dtbo_a};" \ + "name=dtbo_b,size=8M,uuid=${uuid_gpt_dtbo_b};" \ + "name=vbmeta_a,size=64K,uuid=${uuid_gpt_vbmeta_a};" \ + "name=vbmeta_b,size=64K,uuid=${uuid_gpt_vbmeta_b};" \ + "name=recovery,size=64M,uuid=${uuid_gpt_recovery};" \ + "name=super,size=2560M,uuid=${uuid_gpt_super};" \ + "name=metadata,size=16M,uuid=${uuid_gpt_metadata};" \ "name=userdata,size=-,uuid=${uuid_gpt_userdata}" #endif /* PARTS_DEFAULT */
@@ -72,7 +55,7 @@ #define CONTROL_PARTITION "misc"
#if defined(CONFIG_CMD_AB_SELECT) -#define AB_SELECT \ +#define AB_SELECT_SLOT \ "if part number mmc 1 " CONTROL_PARTITION " control_part_number; " \ "then " \ "echo " CONTROL_PARTITION \ @@ -82,18 +65,12 @@ "echo " CONTROL_PARTITION " partition not found;" \ "exit;" \ "fi;" \ - "setenv slot_suffix _${slot_name};" \ - "if part number mmc ${mmcdev} system${slot_suffix} " \ - "system_part_number; then " \ - "setenv bootargs_ab " \ - "ro root=/dev/mmcblk${mmcdev}p${system_part_number} " \ - "rootwait init=/init skip_initramfs " \ - "androidboot.slot_suffix=${slot_suffix};" \ - "echo A/B cmdline addition: ${bootargs_ab};" \ - "setenv bootargs ${bootargs} ${bootargs_ab};" \ - "else " \ - "echo system${slot_suffix} partition not found;" \ - "fi;" + "setenv slot_suffix _${slot_name};" + +#define AB_SELECT_ARGS \ + "setenv bootargs_ab androidboot.slot_suffix=${slot_suffix}; " \ + "echo A/B cmdline addition: ${bootargs_ab};" \ + "setenv bootargs ${bootargs} ${bootargs_ab};" #else #define AB_SELECT "" #endif @@ -121,46 +98,46 @@ "setenv mmcroot /dev/mmcblk0p2 rw; " \ "run mmcboot;\0" \ "emmc_android_boot=" \ + "setenv mmcdev 1; " \ + "mmc dev $mmcdev; " \ + "mmc rescan; " \ + AB_SELECT_SLOT \ "if bcb load " __stringify(CONFIG_FASTBOOT_FLASH_MMC_DEV) " " \ CONTROL_PARTITION "; then " \ + "setenv ardaddr -; " \ "if bcb test command = bootonce-bootloader; then " \ - "echo BCB: Bootloader boot...; " \ + "echo Android: Bootloader boot...; " \ "bcb clear command; bcb store; " \ FASTBOOT_CMD \ + "exit; " \ "elif bcb test command = boot-recovery; then " \ - "echo BCB: Recovery boot...; " \ - "echo Warning: recovery is not implemented; " \ - "echo Performing normal boot for now...; " \ - "bcb clear command; bcb store; " \ - "run emmc_android_normal_boot; " \ + "echo Android: Recovery boot...; " \ + "setenv ardaddr $loadaddr;" \ + "setenv apart recovery; " \ "else " \ - "echo BCB: Normal boot requested...; " \ - "run emmc_android_normal_boot; " \ + "echo Android: Normal boot...; " \ + "setenv ardaddr $loadaddr; " \ + "setenv apart boot${slot_suffix}; " \ "fi; " \ "else " \ "echo Warning: BCB is corrupted or does not exist; " \ - "echo Performing normal boot...; " \ - "run emmc_android_normal_boot; " \ - "fi;\0" \ - "emmc_android_normal_boot=" \ - "echo Trying to boot Android from eMMC ...; " \ - "run update_to_fit; " \ + "echo Android: Normal boot...; " \ + "fi; " \ "setenv eval_bootargs setenv bootargs $bootargs; " \ "run eval_bootargs; " \ - "setenv mmcdev 1; " \ "setenv machid fe6; " \ - "mmc dev $mmcdev; " \ - "mmc rescan; " \ AVB_VERIFY_CHECK \ - AB_SELECT \ - "if part start mmc ${mmcdev} boot${slot_suffix} boot_start; " \ - "then " \ - "part size mmc ${mmcdev} boot${slot_suffix} " \ - "boot_size; " \ - "mmc read ${loadaddr} ${boot_start} ${boot_size}; " \ - "bootm ${loadaddr}#${fdtfile}; " \ + AB_SELECT_ARGS \ + "if part start mmc $mmcdev $apart boot_start; then " \ + "part size mmc $mmcdev $apart boot_size; " \ + "mmc read $loadaddr $boot_start $boot_size; " \ + "bootimg get_dtb_file 0 dtb_start dtb_size; " \ + "cp.b $dtb_start $fdtaddr $dtb_size; " \ + "fdt addr $fdtaddr; " \ + "bootm $loadaddr $ardaddr $fdtaddr; " \ "else " \ - "echo boot${slot_suffix} partition not found; " \ + "echo $apart partition not found; " \ + "exit; " \ "fi;\0"
#ifdef CONFIG_OMAP54XX

Read correct dtb file from boot.img/recovery.img and apply correct dtbo files from dtbo partition.
Signed-off-by: Sam Protsenko semen.protsenko@linaro.org --- include/configs/ti_armv7_common.h | 7 +++++ include/environment/ti/boot.h | 44 ++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h index 2de6bc2390..188171e4c4 100644 --- a/include/configs/ti_armv7_common.h +++ b/include/configs/ti_armv7_common.h @@ -37,11 +37,18 @@ * seen large trees). We say all of this must be within the first 256MB * as that will normally be within the kernel lowmem and thus visible via * bootm_size and we only run on platforms with 256MB or more of memory. + * + * As a temporary storage for DTBO files (which should be applied into DTB + * file), we use the location 15.5 MB above the ramdisk. If someone wants to + * use ramdisk bigger than 15.5 MB, then DTBO can be loaded and applied to DTB + * file before loading the ramdisk, as DTBO location is only used as a temporary + * storage, and can be re-used after 'fdt apply' command is done. */ #define DEFAULT_LINUX_BOOT_ENV \ "loadaddr=0x82000000\0" \ "kernel_addr_r=0x82000000\0" \ "fdtaddr=0x88000000\0" \ + "dtboaddr=0x89000000\0" \ "fdt_addr_r=0x88000000\0" \ "rdaddr=0x88080000\0" \ "ramdisk_addr_r=0x88080000\0" \ diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h index a7644a5874..1b2b923842 100644 --- a/include/environment/ti/boot.h +++ b/include/environment/ti/boot.h @@ -75,6 +75,46 @@ #define AB_SELECT "" #endif
+/* + * Prepares complete device tree file for current board (for Android boot). + * + * Boot image or recovery image should be loaded into $loadaddr prior to running + * these commands. The logic of these commnads is next: + * + * 1. Read correct DTB file for current SoC/board from boot image in $loadaddr + * to $fdtaddr + * 2. Merge all needed DTBO files for current board from 'dtbo' partition + * into read DTB file + * 3. User should provide $fdtaddr as 3rd argument to 'bootm' + * + * XXX: Why passing 0x100000 to 'fdt addr'? Maybe omit it (it's optional)? + */ +#define PREPARE_FDT \ + "echo ---> Preparing FDT...; " \ + "if test $board_name = am57xx_evm_reva3; then " \ + "echo " -> Reading DTBO partition..."; " \ + "part start mmc ${mmcdev} dtbo${slot_suffix} p_dtbo_start; " \ + "part size mmc ${mmcdev} dtbo${slot_suffix} p_dtbo_size; " \ + "mmc read ${dtboaddr} ${p_dtbo_start} ${p_dtbo_size}; " \ + "echo " -> Reading DTB file for AM57x EVM RevA3..."; " \ + "bootimg get_dtb_file 0 dtb_start dtb_size; " \ + "cp.b $dtb_start $fdtaddr $dtb_size; " \ + "fdt addr $fdtaddr 0x100000; " \ + "echo " -> Applying DTBOs for AM57x EVM RevA3..."; " \ + "dtimg start ${dtboaddr} 0 dtbo_addr; " \ + "fdt apply $dtbo_addr; " \ + "dtimg start ${dtboaddr} 1 dtbo_addr; " \ + "fdt apply $dtbo_addr; " \ + "elif test $board_name = beagle_x15_revc; then " \ + "echo " -> Reading DTB file for Beagle X15 RevC..."; " \ + "bootimg get_dtb_file 0 dtb_start dtb_size; " \ + "cp.b $dtb_start $fdtaddr $dtb_size; " \ + "fdt addr $fdtaddr 0x100000; " \ + "else " \ + "echo Error: Android boot is not supported for $board_name; " \ + "exit; " \ + "fi; " \ + #define FASTBOOT_CMD \ "echo Booting into fastboot ...; " \ "fastboot " __stringify(CONFIG_FASTBOOT_USB_DEV) "; " @@ -131,9 +171,7 @@ "if part start mmc $mmcdev $apart boot_start; then " \ "part size mmc $mmcdev $apart boot_size; " \ "mmc read $loadaddr $boot_start $boot_size; " \ - "bootimg get_dtb_file 0 dtb_start dtb_size; " \ - "cp.b $dtb_start $fdtaddr $dtb_size; " \ - "fdt addr $fdtaddr; " \ + PREPARE_FDT \ "bootm $loadaddr $ardaddr $fdtaddr; " \ "else " \ "echo $apart partition not found; " \

Hi Sam,
On Thu, Sep 19, 2019 at 08:28:15PM +0300, Sam Protsenko wrote:
Android 10 brings a lot of new requirements for bootloaders: [1]. This patch series attempts to implement such a boot process on BeagleBoard X15 platform. Some common code is added too, which can be reused later for other platforms.
First, many thanks and true appreciation for making the bring-up of the same features easier on other platforms. Big thumbs up.
Since I wanted to include some backtraces, I've posted my review findings (1st round) in https://paste.ubuntu.com/p/jNwYP99kp8/.

Hi Eugeniu,
On Thu, Sep 19, 2019 at 9:23 PM Eugeniu Rosca roscaeugeniu@gmail.com wrote:
Hi Sam,
On Thu, Sep 19, 2019 at 08:28:15PM +0300, Sam Protsenko wrote:
Android 10 brings a lot of new requirements for bootloaders: [1]. This patch series attempts to implement such a boot process on BeagleBoard X15 platform. Some common code is added too, which can be reused later for other platforms.
First, many thanks and true appreciation for making the bring-up of the same features easier on other platforms. Big thumbs up.
Since I wanted to include some backtraces, I've posted my review findings (1st round) in https://paste.ubuntu.com/p/jNwYP99kp8/.
Thanks for your input. All issues you mentioned should be fixed in v2 I sent recently. Can you please check it out too?
-- Best Regards, Eugeniu

Hi Sam,
On Wed, Oct 23, 2019 at 10:37:23PM +0300, Sam Protsenko wrote: [..]
Thanks for your input. All issues you mentioned should be fixed in v2 I sent recently. Can you please check it out too?
Thanks for the notification. I will review v2 in the following days. Congrats with the awesome presentation and slides.
participants (4)
-
Eugeniu Rosca
-
Igor Opaniuk
-
Sam Protsenko
-
Simon Glass