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 */ 23 static 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 55 static 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 109 U_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 ); 127