[U-Boot] [PATCH 6/6] cmd: Add "boot_android" command.
Stanislas BERTRAND
sbertrand at witekio.com
Thu Apr 19 17:21:33 UTC 2018
Hi Alex,
I used work available in https://android.googlesource.com/platform/external/u-boot/+/android-o-mr1-iot-preview-7.
I selected the n-iot-preview-4 because it is U-Boot version 2017.01 which is compatible with TI U-Boot work.
One quick feedback about the boot_android :
> The new "boot_android" command simply executes the Android Bootloader
> flow. This receives the location (interface, dev, partition) of the
> Android "misc" partition which is then used to lookup and infer the
> kernel and system images that should be booted from the passed slot.
>
> Test: Booted a rpi3 build with Android Things.
> Signed-off-by: Alex Deymo <deymo at google.com>
> ---
> README | 6 +++
> cmd/Kconfig | 10 +++++
> cmd/Makefile | 1 +
> cmd/boot_android.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 143 insertions(+)
> create mode 100644 cmd/boot_android.c
>
> diff --git a/README b/README
> index 384cc6aabb..5f62e14d94 100644
> --- a/README
> +++ b/README
> @@ -1484,6 +1484,12 @@ The following options need to be configured:
> sending again an USB request to the device.
>
> - Android Bootloader support:
> + CONFIG_CMD_BOOT_ANDROID
> + This enables the command "boot_android" which executes the
> + Android Bootloader flow. Enabling CONFIG_CMD_FASTBOOT is
> + recommended to support the Android Fastboot protocol as part
> + of the bootloader.
> +
> CONFIG_ANDROID_BOOTLOADER
> This enables support for the Android bootloader flow. Android
> devices can boot in normal mode, recovery mode or bootloader
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 87a445d269..c4c22464b1 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -431,6 +431,16 @@ config CMD_LOAD_ANDROID
> define the size and kernel address on the header, which are used by
> this command.
>
> +config CMD_BOOT_ANDROID
> + bool "boot_android"
> + default n
> + depends on ANDROID_BOOTLOADER
> + help
> + Performs the Android Bootloader boot flow, loading the appropriate
> + Android image (normal kernel, recovery kernel or "bootloader" mode)
> + and booting it. The boot mode is determined by the contents of the
> + Android Bootloader Message.
> +
> config CMD_FLASH
> bool "flinfo, erase, protect"
> default y
> diff --git a/cmd/Makefile b/cmd/Makefile
> index 2f75dab040..348cf75386 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -22,6 +22,7 @@ obj-$(CONFIG_CMD_BDI) += bdinfo.o
> obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
> obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
> obj-$(CONFIG_CMD_BMP) += bmp.o
> +obj-$(CONFIG_CMD_BOOT_ANDROID) += boot_android.o
> obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o
> obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o
> obj-$(CONFIG_CMD_BOOTLDR) += bootldr.o
> diff --git a/cmd/boot_android.c b/cmd/boot_android.c
> new file mode 100644
> index 0000000000..067d9c7637
> --- /dev/null
> +++ b/cmd/boot_android.c
> @@ -0,0 +1,126 @@
> +/*
> + * Copyright (C) 2016 The Android Open Source Project
> + *
> + * SPDX-License-Identifier: BSD-2-Clause
> + */
> +
> +#include <android_bootloader.h>
> +#include <common.h>
> +#include <command.h>
> +
> +/**
> + * part_get_info_by_dev_and_name - Parse a device number and partition name
> + * string in the form of "device_num;partition_name", for example "0;misc".
> + * If the partition is found, sets dev_desc and part_info accordingly with the
> + * information of the partition with the given partition_name.
> + *
> + * @dev_iface: Device interface.
> + * @dev_part_str: Input string argument, like "0;misc".
> + * @dev_desc: Place to put the device description pointer.
> + * @part_info: Place to put the partition information.
> + * @return 0 on success, or -1 on error
> + */
> +static int part_get_info_by_dev_and_name(const char *dev_iface,
> + const char *dev_part_str,
> + struct blk_desc **dev_desc,
> + disk_partition_t *part_info)
> +{
> + char *ep;
> + const char *part_str;
> + int dev_num;
> +
> + part_str = strchr(dev_part_str, ';');
> + if (!part_str)
> + return -1;
> +
> + dev_num = simple_strtoul(dev_part_str, &ep, 16);
> + if (ep != part_str) {
> + /* Not all the first part before the ; was parsed. */
> + return -1;
> + }
> + part_str++;
> +
> + *dev_desc = blk_get_dev(dev_iface, dev_num);
> + if (!*dev_desc) {
> + printf("Could not find %s %d\n", dev_iface, dev_num);
> + return -1;
> + }
> + if (part_get_info_by_name(*dev_desc, part_str, part_info) < 0) {
> + printf("Could not find \"%s\" partition\n", part_str);
> + return -1;
> + }
> + return 0;
> +}
> +
> +static int do_boot_android(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[])
> +{
> + unsigned long load_address;
> + int ret = CMD_RET_SUCCESS;
> + char *addr_arg_endp, *addr_str;
> + struct blk_desc *dev_desc;
> + disk_partition_t part_info;
> + const char *misc_part_iface;
> + const char *misc_part_desc;
> +
> + if (argc < 4)
> + return CMD_RET_USAGE;
> + if (argc > 5)
> + return CMD_RET_USAGE;
> +
> + if (argc >= 5) {
> + load_address = simple_strtoul(argv[4], &addr_arg_endp, 16);
> + if (addr_arg_endp == argv[4] || *addr_arg_endp != '\0')
> + return CMD_RET_USAGE;
> + } else {
> + addr_str = getenv("loadaddr");
> + if (addr_str)
> + load_address = simple_strtoul(addr_str, NULL, 16);
> + else
> + load_address = CONFIG_SYS_LOAD_ADDR;
> + }
> +
> + /* Lookup the "misc" partition from argv[1] and argv[2] */
> + misc_part_iface = argv[1];
> + misc_part_desc = argv[2];
> + /* Split the part_name if passed as "$dev_num;part_name". */
> + if (part_get_info_by_dev_and_name(misc_part_iface, misc_part_desc,
> + &dev_desc, &part_info) < 0) {
> + /* Couldn't lookup by name from mmc, try looking up the
> + * partition description directly.
> + */
> + if (blk_get_device_part_str(misc_part_iface, misc_part_desc,
> + &dev_desc, &part_info, 1) < 0) {
> + printf("Couldn't find partition %s %s\n",
> + misc_part_iface, misc_part_desc);
> + return CMD_RET_FAILURE;
> + }
> + }
> +
> + ret = android_bootloader_boot_flow(dev_desc, &part_info, argv[3],
> + load_address);
> + if (ret < 0) {
> + printf("Android boot failed, error %d.\n", ret);
> + return CMD_RET_FAILURE;
> + }
> + return CMD_RET_SUCCESS;
> +}
> +
> +U_BOOT_CMD(
> + boot_android, 5, 0, do_boot_android,
> + "Execute the Android Bootloader flow.",
> + "<interface> <dev[:part|;part_name]> <slot> [<kernel_addr>]\n"
> + " - Load the Boot Control Block (BCB) from the partition 'part' on\n"
> + " device type 'interface' instance 'dev' to determine the boot\n"
> + " mode, and load and execute the appropriate kernel.\n"
> + " In normal and recovery mode, the kernel will be loaded from\n"
> + " the corresponding \"boot\" partition. In bootloader mode, the\n"
> + " command defined in the \"fastbootcmd\" variable will be\n"
> + " executed.\n"
> + " On Android devices with multiple slots, the pass 'slot' is\n"
> + " used to load the appropriate kernel. The standard slot names\n"
> + " are 'a' and 'b'.\n"
The part name will be used to find the partition if `;` is used. `;` is the command delimiter
for u-boot commands. When using it with the `boot` partition, the `boot` command would
be executed and boot_android would return a failure.
Could part number and part name be handle in software, if name lookup fails, try a
number conversion.
> + " - If 'part_name' is passed, preceded with a ; instead of :, the\n"
> + " partition name whose label is 'part_name' will be looked up in\n"
> + " the partition table. This is commonly the \"misc\" partition.\n"
> +);
> --
>
More information about the U-Boot
mailing list