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
Test: Booted a rpi3 build with Android Things.
Signed-off-by: Alex Deymo <deymo@google.com>

Change-Id: Ibf3f31e38b159d42db7a0835b99ad7ec260fc2a7
This commit is contained in:
Alex Deymo 2016-12-01 14:21:51 -08:00 committed by Kever Yang
parent 67dac67453
commit 06f4a8746e
4 changed files with 154 additions and 0 deletions

6
README
View File

@ -1243,6 +1243,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

View File

@ -752,6 +752,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_MMC
bool "mmc"
help

View File

@ -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_BOOTSTAGE) += bootstage.o

137
cmd/boot_android.c Normal file
View File

@ -0,0 +1,137 @@
/*
* 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. Only "mmc" is supported at the moment.
* @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)
{
#ifdef CONFIG_EFI_PARTITION
char *ep;
const char *part_str;
int dev_num;
/* We only support "mmc" for looking up partition names. */
if (strcmp(dev_iface, "mmc") != 0)
return -1;
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("mmc", dev_num);
if (!*dev_desc) {
printf("Could not find mmc %d\n", 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;
#else
return -1;
#endif /* CONFIG_EFI_PARTITION */
}
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 < 3)
return CMD_RET_USAGE;
if (argc > 4)
return CMD_RET_USAGE;
if (argc >= 4) {
load_address = simple_strtoul(argv[3], &addr_arg_endp, 16);
if (addr_arg_endp == argv[3] || *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(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, 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, 4, 0, do_boot_android,
"Execute the Android Bootloader flow.",
"<interface> <dev[:part"
#if defined(CONFIG_EFI_PARTITION)
/* When EFI is enabled we also support looking up a partition name. */
"|;part_name"
#endif /* CONFIG_EFI_PARTITION */
"]> [<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"
#if defined(CONFIG_EFI_PARTITION)
" - 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"
#endif /* CONFIG_EFI_PARTITION */
);