aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deymo <deymo@google.com>2016-12-01 14:21:51 -0800
committerAlistair Delva <adelva@google.com>2020-10-02 07:16:53 -0700
commitb2e2db95cf93352b2de5f4d7f55e0258cb18bcde (patch)
tree385b2efa58f29bc81f23cebdf0fa98b358d02f09
parent62dabc44f384f546e69c5b0d660e7a0bdd9955bc (diff)
downloadplatform_external_u-boot-b2e2db95cf93352b2de5f4d7f55e0258cb18bcde.tar.gz
platform_external_u-boot-b2e2db95cf93352b2de5f4d7f55e0258cb18bcde.tar.bz2
platform_external_u-boot-b2e2db95cf93352b2de5f4d7f55e0258cb18bcde.zip
ANDROID: Add "boot_android" command.
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. Bug: 32707546 Bug: 141272741 Bug: 169336575 Test: Booted a rpi3 build with Android Things. Signed-off-by: Alex Deymo <deymo@google.com> Signed-off-by: Alistair Strachan <astrachan@google.com> [dvander: renamed fdt_addr to fdtaddr] Signed-off-by: David Anderson <dvander@google.com> [rammuthiah: Updated change to build post v2020.10 merge] Signed-off-by: Ram Muthiah <rammuthiah@google.com> Change-Id: I6bc306e097c95d52a7e4a8b02677a4b9b636d8e1
-rw-r--r--README6
-rw-r--r--cmd/Kconfig10
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/boot_android.c74
-rw-r--r--common/android_bootloader.c25
-rw-r--r--include/android_bootloader.h6
6 files changed, 116 insertions, 6 deletions
diff --git a/README b/README
index cf1e4f1ddd..e835dcd6c1 100644
--- a/README
+++ b/README
@@ -1136,6 +1136,12 @@ The following options need to be configured:
"bootloader", which often means reboot to fastboot but may also
include a UI with a menu.
+ 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.
+
- Journaling Flash filesystem support:
CONFIG_JFFS2_NAND
Define these for a default partition on a NAND device
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 0c984d735d..71761d409c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1463,6 +1463,16 @@ config CMD_AB_SELECT
is used by the new A/B update model where one slot is updated in the
background while running from the other slot.
+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.
+
endmenu
if NET
diff --git a/cmd/Makefile b/cmd/Makefile
index 3a9c9747c9..9b93ecee25 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_CMD_BIND) += bind.o
obj-$(CONFIG_CMD_BINOP) += binop.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_BOOTCOUNT) += bootcount.o
obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o
obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o
diff --git a/cmd/boot_android.c b/cmd/boot_android.c
new file mode 100644
index 0000000000..964168946f
--- /dev/null
+++ b/cmd/boot_android.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <android_bootloader.h>
+#include <common.h>
+#include <command.h>
+#include <part.h>
+
+static int do_boot_android(struct cmd_tbl *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;
+ struct disk_partition 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 = env_get("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_or_num(misc_part_iface,
+ misc_part_desc,
+ &dev_desc, &part_info) < 0)
+ 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"
+ " - 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"
+);
diff --git a/common/android_bootloader.c b/common/android_bootloader.c
index 770c40b297..46dd282d5e 100644
--- a/common/android_bootloader.c
+++ b/common/android_bootloader.c
@@ -130,12 +130,17 @@ static int android_part_get_info_by_name_suffix(struct blk_desc *dev_desc,
{
char *part_name;
int part_num;
+ size_t part_name_len;
- part_name = malloc(strlen(base_name) + strlen(slot_suffix) + 1);
+ part_name_len = strlen(base_name) + 1;
+ if (slot_suffix)
+ part_name_len += strlen(slot_suffix);
+ part_name = malloc(part_name_len);
if (!part_name)
return -1;
strcpy(part_name, base_name);
- strcat(part_name, slot_suffix);
+ if (slot_suffix)
+ strcat(part_name, slot_suffix);
part_num = part_get_info_by_name(dev_desc, part_name, part_info);
if (part_num < 0) {
@@ -159,8 +164,9 @@ static int android_bootloader_boot_bootloader(void)
static int android_bootloader_boot_kernel(unsigned long kernel_address)
{
char kernel_addr_str[12];
- char *fdt_addr = env_get("fdt_addr");
- char *bootm_args[] = { "bootm", kernel_addr_str, "-", fdt_addr, NULL };
+ char *fdt_addr = env_get("fdtaddr");
+ char *bootm_args[] = {
+ "bootm", kernel_addr_str, kernel_addr_str, fdt_addr, NULL };
sprintf(kernel_addr_str, "0x%lx", kernel_address);
@@ -260,6 +266,7 @@ static char *android_assemble_cmdline(const char *slot_suffix,
int android_bootloader_boot_flow(struct blk_desc *dev_desc,
const struct disk_partition *misc_part_info,
+ const char *slot,
unsigned long kernel_address)
{
enum android_boot_mode mode;
@@ -268,8 +275,7 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
int boot_part_num, system_part_num;
int ret;
char *command_line;
- /* TODO: lookup the slot_suffix based on the BCB. */
- const char *slot_suffix = "_a";
+ char slot_suffix[3];
const char *mode_cmdline = NULL;
/* Determine the boot mode and clear its value for the next boot if
@@ -299,6 +305,13 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
return android_bootloader_boot_bootloader();
}
+ slot_suffix[0] = '\0';
+ if (slot && slot[0]) {
+ slot_suffix[0] = '_';
+ slot_suffix[1] = slot[0];
+ slot_suffix[2] = '\0';
+ }
+
/* Load the kernel from the desired "boot" partition. */
boot_part_num =
android_part_get_info_by_name_suffix(dev_desc,
diff --git a/include/android_bootloader.h b/include/android_bootloader.h
index d9cfdd589b..114ca5ddcf 100644
--- a/include/android_bootloader.h
+++ b/include/android_bootloader.h
@@ -36,10 +36,16 @@ struct disk_partition;
* The boot mode is determined by the contents of the Android Bootloader
* Message. On success it doesn't return.
*
+ * @dev_desc: device where to load the kernel and system to boot from.
+ * @misc_part_info: the "misc" partition descriptor in 'dev_desc'.
+ * @slot: the boot slot to boot from.
+ * @kernel_address: address where to load the kernel if needed.
+ *
* @return a negative number in case of error, otherwise it doesn't return.
*/
int android_bootloader_boot_flow(struct blk_desc *dev_desc,
const struct disk_partition *misc_part_info,
+ const char *slot,
unsigned long kernel_address);
#endif /* __ANDROID_BOOTLOADER_H */