aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deymo2016-12-01 16:21:51 -0600
committerAlistair Strachan2018-08-10 21:54:55 -0500
commit0ec64604e347544b09428ef7badd6ed3554a40a6 (patch)
tree4651ae3aef05aec7820e1b07169a44852eee4f4d
parent6a078de7682f595c93a7720fa447ecdd6b585610 (diff)
downloadu-boot-0ec64604e347544b09428ef7badd6ed3554a40a6.tar.gz
u-boot-0ec64604e347544b09428ef7badd6ed3554a40a6.tar.xz
u-boot-0ec64604e347544b09428ef7badd6ed3554a40a6.zip
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
-rw-r--r--README6
-rw-r--r--cmd/Kconfig10
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/boot_android.c126
-rw-r--r--common/android_bootloader.c23
-rw-r--r--include/android_bootloader.h6
6 files changed, 167 insertions, 5 deletions
diff --git a/README b/README
index 45f1d5160f..51e93c836a 100644
--- a/README
+++ b/README
@@ -1207,6 +1207,12 @@ The following options need to be configured:
1207 sending again an USB request to the device. 1207 sending again an USB request to the device.
1208 1208
1209- Android Bootloader support: 1209- Android Bootloader support:
1210 CONFIG_CMD_BOOT_ANDROID
1211 This enables the command "boot_android" which executes the
1212 Android Bootloader flow. Enabling CONFIG_CMD_FASTBOOT is
1213 recommended to support the Android Fastboot protocol as part
1214 of the bootloader.
1215
1210 CONFIG_ANDROID_BOOTLOADER 1216 CONFIG_ANDROID_BOOTLOADER
1211 This enables support for the Android bootloader flow. Android 1217 This enables support for the Android bootloader flow. Android
1212 devices can boot in normal mode, recovery mode or bootloader 1218 devices can boot in normal mode, recovery mode or bootloader
diff --git a/cmd/Kconfig b/cmd/Kconfig
index aec209006d..ef8d9cba0b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -607,6 +607,16 @@ config CMD_ADC
607 Shows ADC device info and permit printing one-shot analog converted 607 Shows ADC device info and permit printing one-shot analog converted
608 data from a named Analog to Digital Converter. 608 data from a named Analog to Digital Converter.
609 609
610config CMD_BOOT_ANDROID
611 bool "boot_android"
612 default n
613 depends on ANDROID_BOOTLOADER
614 help
615 Performs the Android Bootloader boot flow, loading the appropriate
616 Android image (normal kernel, recovery kernel or "bootloader" mode)
617 and booting it. The boot mode is determined by the contents of the
618 Android Bootloader Message.
619
610config CMD_CLK 620config CMD_CLK
611 bool "clk - Show clock frequencies" 621 bool "clk - Show clock frequencies"
612 help 622 help
diff --git a/cmd/Makefile b/cmd/Makefile
index 323f1fd2c7..95508385f6 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
22obj-$(CONFIG_CMD_BINOP) += binop.o 22obj-$(CONFIG_CMD_BINOP) += binop.o
23obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o 23obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
24obj-$(CONFIG_CMD_BMP) += bmp.o 24obj-$(CONFIG_CMD_BMP) += bmp.o
25obj-$(CONFIG_CMD_BOOT_ANDROID) += boot_android.o
25obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o 26obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o
26obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o 27obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o
27obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o 28obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o
diff --git a/cmd/boot_android.c b/cmd/boot_android.c
new file mode 100644
index 0000000000..a2148e0238
--- /dev/null
+++ b/cmd/boot_android.c
@@ -0,0 +1,126 @@
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <android_bootloader.h>
8#include <common.h>
9#include <command.h>
10
11/**
12 * part_get_info_by_dev_and_name - Parse a device number and partition name
13 * string in the form of "device_num;partition_name", for example "0;misc".
14 * If the partition is found, sets dev_desc and part_info accordingly with the
15 * information of the partition with the given partition_name.
16 *
17 * @dev_iface: Device interface.
18 * @dev_part_str: Input string argument, like "0;misc".
19 * @dev_desc: Place to put the device description pointer.
20 * @part_info: Place to put the partition information.
21 * @return 0 on success, or -1 on error
22 */
23static int part_get_info_by_dev_and_name(const char *dev_iface,
24 const char *dev_part_str,
25 struct blk_desc **dev_desc,
26 disk_partition_t *part_info)
27{
28 char *ep;
29 const char *part_str;
30 int dev_num;
31
32 part_str = strchr(dev_part_str, ';');
33 if (!part_str)
34 return -1;
35
36 dev_num = simple_strtoul(dev_part_str, &ep, 16);
37 if (ep != part_str) {
38 /* Not all the first part before the ; was parsed. */
39 return -1;
40 }
41 part_str++;
42
43 *dev_desc = blk_get_dev(dev_iface, dev_num);
44 if (!*dev_desc) {
45 printf("Could not find %s %d\n", dev_iface, dev_num);
46 return -1;
47 }
48 if (part_get_info_by_name(*dev_desc, part_str, part_info) < 0) {
49 printf("Could not find \"%s\" partition\n", part_str);
50 return -1;
51 }
52 return 0;
53}
54
55static int do_boot_android(cmd_tbl_t *cmdtp, int flag, int argc,
56 char * const argv[])
57{
58 unsigned long load_address;
59 int ret = CMD_RET_SUCCESS;
60 char *addr_arg_endp, *addr_str;
61 struct blk_desc *dev_desc;
62 disk_partition_t part_info;
63 const char *misc_part_iface;
64 const char *misc_part_desc;
65
66 if (argc < 4)
67 return CMD_RET_USAGE;
68 if (argc > 5)
69 return CMD_RET_USAGE;
70
71 if (argc >= 5) {
72 load_address = simple_strtoul(argv[4], &addr_arg_endp, 16);
73 if (addr_arg_endp == argv[4] || *addr_arg_endp != '\0')
74 return CMD_RET_USAGE;
75 } else {
76 addr_str = env_get("loadaddr");
77 if (addr_str)
78 load_address = simple_strtoul(addr_str, NULL, 16);
79 else
80 load_address = CONFIG_SYS_LOAD_ADDR;
81 }
82
83 /* Lookup the "misc" partition from argv[1] and argv[2] */
84 misc_part_iface = argv[1];
85 misc_part_desc = argv[2];
86 /* Split the part_name if passed as "$dev_num;part_name". */
87 if (part_get_info_by_dev_and_name(misc_part_iface, misc_part_desc,
88 &dev_desc, &part_info) < 0) {
89 /* Couldn't lookup by name from mmc, try looking up the
90 * partition description directly.
91 */
92 if (blk_get_device_part_str(misc_part_iface, misc_part_desc,
93 &dev_desc, &part_info, 1) < 0) {
94 printf("Couldn't find partition %s %s\n",
95 misc_part_iface, misc_part_desc);
96 return CMD_RET_FAILURE;
97 }
98 }
99
100 ret = android_bootloader_boot_flow(dev_desc, &part_info, argv[3],
101 load_address);
102 if (ret < 0) {
103 printf("Android boot failed, error %d.\n", ret);
104 return CMD_RET_FAILURE;
105 }
106 return CMD_RET_SUCCESS;
107}
108
109U_BOOT_CMD(
110 boot_android, 5, 0, do_boot_android,
111 "Execute the Android Bootloader flow.",
112 "<interface> <dev[:part|;part_name]> <slot> [<kernel_addr>]\n"
113 " - Load the Boot Control Block (BCB) from the partition 'part' on\n"
114 " device type 'interface' instance 'dev' to determine the boot\n"
115 " mode, and load and execute the appropriate kernel.\n"
116 " In normal and recovery mode, the kernel will be loaded from\n"
117 " the corresponding \"boot\" partition. In bootloader mode, the\n"
118 " command defined in the \"fastbootcmd\" variable will be\n"
119 " executed.\n"
120 " On Android devices with multiple slots, the pass 'slot' is\n"
121 " used to load the appropriate kernel. The standard slot names\n"
122 " are 'a' and 'b'.\n"
123 " - If 'part_name' is passed, preceded with a ; instead of :, the\n"
124 " partition name whose label is 'part_name' will be looked up in\n"
125 " the partition table. This is commonly the \"misc\" partition.\n"
126);
diff --git a/common/android_bootloader.c b/common/android_bootloader.c
index 059eb6a92d..fbfe3de50c 100644
--- a/common/android_bootloader.c
+++ b/common/android_bootloader.c
@@ -126,12 +126,17 @@ static int android_part_get_info_by_name_suffix(struct blk_desc *dev_desc,
126{ 126{
127 char *part_name; 127 char *part_name;
128 int part_num; 128 int part_num;
129 size_t part_name_len;
129 130
130 part_name = malloc(strlen(base_name) + strlen(slot_suffix) + 1); 131 part_name_len = strlen(base_name) + 1;
132 if (slot_suffix)
133 part_name_len += strlen(slot_suffix);
134 part_name = malloc(part_name_len);
131 if (!part_name) 135 if (!part_name)
132 return -1; 136 return -1;
133 strcpy(part_name, base_name); 137 strcpy(part_name, base_name);
134 strcat(part_name, slot_suffix); 138 if (slot_suffix)
139 strcat(part_name, slot_suffix);
135 140
136 part_num = part_get_info_by_name(dev_desc, part_name, part_info); 141 part_num = part_get_info_by_name(dev_desc, part_name, part_info);
137 if (part_num < 0) { 142 if (part_num < 0) {
@@ -156,7 +161,8 @@ static int android_bootloader_boot_kernel(unsigned long kernel_address)
156{ 161{
157 char kernel_addr_str[12]; 162 char kernel_addr_str[12];
158 char *fdt_addr = env_get("fdt_addr"); 163 char *fdt_addr = env_get("fdt_addr");
159 char *bootm_args[] = { "bootm", kernel_addr_str, "-", fdt_addr, NULL }; 164 char *bootm_args[] = {
165 "bootm", kernel_addr_str, kernel_addr_str, fdt_addr, NULL };
160 166
161 sprintf(kernel_addr_str, "0x%lx", kernel_address); 167 sprintf(kernel_addr_str, "0x%lx", kernel_address);
162 168
@@ -256,6 +262,7 @@ static char *android_assemble_cmdline(const char *slot_suffix,
256 262
257int android_bootloader_boot_flow(struct blk_desc *dev_desc, 263int android_bootloader_boot_flow(struct blk_desc *dev_desc,
258 const disk_partition_t *misc_part_info, 264 const disk_partition_t *misc_part_info,
265 const char *slot,
259 unsigned long kernel_address) 266 unsigned long kernel_address)
260{ 267{
261 enum android_boot_mode mode; 268 enum android_boot_mode mode;
@@ -264,8 +271,7 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
264 int boot_part_num, system_part_num; 271 int boot_part_num, system_part_num;
265 int ret; 272 int ret;
266 char *command_line; 273 char *command_line;
267 /* TODO: lookup the slot_suffix based on the BCB. */ 274 char slot_suffix[3];
268 const char *slot_suffix = "_a";
269 const char *mode_cmdline = NULL; 275 const char *mode_cmdline = NULL;
270 276
271 /* Determine the boot mode and clear its value for the next boot if 277 /* Determine the boot mode and clear its value for the next boot if
@@ -295,6 +301,13 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
295 return android_bootloader_boot_bootloader(); 301 return android_bootloader_boot_bootloader();
296 } 302 }
297 303
304 slot_suffix[0] = '\0';
305 if (slot && slot[0]) {
306 slot_suffix[0] = '_';
307 slot_suffix[1] = slot[0];
308 slot_suffix[2] = '\0';
309 }
310
298 /* Load the kernel from the desired "boot" partition. */ 311 /* Load the kernel from the desired "boot" partition. */
299 boot_part_num = 312 boot_part_num =
300 android_part_get_info_by_name_suffix(dev_desc, 313 android_part_get_info_by_name_suffix(dev_desc,
diff --git a/include/android_bootloader.h b/include/android_bootloader.h
index 947913e547..ddf6d76f64 100644
--- a/include/android_bootloader.h
+++ b/include/android_bootloader.h
@@ -33,10 +33,16 @@ enum android_boot_mode {
33 * The boot mode is determined by the contents of the Android Bootloader 33 * The boot mode is determined by the contents of the Android Bootloader
34 * Message. On success it doesn't return. 34 * Message. On success it doesn't return.
35 * 35 *
36 * @dev_desc: device where to load the kernel and system to boot from.
37 * @misc_part_info: the "misc" partition descriptor in 'dev_desc'.
38 * @slot: the boot slot to boot from.
39 * @kernel_address: address where to load the kernel if needed.
40 *
36 * @return a negative number in case of error, otherwise it doesn't return. 41 * @return a negative number in case of error, otherwise it doesn't return.
37 */ 42 */
38int android_bootloader_boot_flow(struct blk_desc *dev_desc, 43int android_bootloader_boot_flow(struct blk_desc *dev_desc,
39 const disk_partition_t *misc_part_info, 44 const disk_partition_t *misc_part_info,
45 const char *slot,
40 unsigned long kernel_address); 46 unsigned long kernel_address);
41 47
42#endif /* __ANDROID_BOOTLOADER_H */ 48#endif /* __ANDROID_BOOTLOADER_H */