Loading fastboot/fastboot.cpp +134 −48 Original line number Diff line number Diff line Loading @@ -99,19 +99,41 @@ struct fastboot_buffer { }; static struct { char img_name[13]; char sig_name[13]; char img_name[17]; char sig_name[17]; char part_name[9]; bool is_optional; bool is_secondary; } images[] = { {"boot.img", "boot.sig", "boot", false}, {"recovery.img", "recovery.sig", "recovery", true}, {"system.img", "system.sig", "system", false}, {"vendor.img", "vendor.sig", "vendor", true}, {"boot.img", "boot.sig", "boot", false, false}, {"boot_other.img", "boot.sig", "boot", true, true}, {"recovery.img", "recovery.sig", "recovery", true, false}, {"system.img", "system.sig", "system", false, false}, {"system_other.img", "system.sig", "system", true, true}, {"vendor.img", "vendor.sig", "vendor", true, false}, {"vendor_other.img", "vendor.sig", "vendor", true, true}, }; static std::string find_item(const char* item, const char* product) { static std::string find_item_given_name(const char* img_name, const char* product) { char *dir; if(product) { std::string path = get_my_path(); return android::base::StringPrintf("%s/../../../target/product/%s/%s", path.c_str(), product, img_name); } dir = getenv("ANDROID_PRODUCT_OUT"); if((dir == 0) || (dir[0] == 0)) { die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); } return android::base::StringPrintf("%s/%s", dir, img_name); } std::string find_item(const char* item, const char* product) { const char *fn; if(!strcmp(item,"boot")) { fn = "boot.img"; } else if(!strcmp(item,"recovery")) { Loading @@ -131,19 +153,7 @@ static std::string find_item(const char* item, const char* product) { return ""; } if (product) { std::string path = get_my_path(); path.erase(path.find_last_of('/')); return android::base::StringPrintf("%s/../../../target/product/%s/%s", path.c_str(), product, fn); } char* dir = getenv("ANDROID_PRODUCT_OUT"); if (dir == nullptr || dir[0] == '\0') { die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); } return android::base::StringPrintf("%s/%s", dir, fn); return find_item_given_name(fn, product); } static int64_t get_file_size(int fd) { Loading Loading @@ -314,6 +324,11 @@ static void usage() { " if found -- recovery. If the device\n" " supports slots, the slot that has\n" " been flashed to is set as active.\n" " Secondary images may be flashed to\n" " an inactive slot.\n" " flash-primary Same as flashall, but do not flash\n" " secondary images.\n" " flash-secondary Only flashes the secondary images.\n" " flash <partition> [ <filename> ] Write a file to a flash partition.\n" " flashing lock Locks the device. Prevents flashing.\n" " flashing unlock Unlocks the device. Allows flashing\n" Loading Loading @@ -858,8 +873,12 @@ static std::vector<std::string> get_suffixes(Transport* transport) { return suffixes; } static bool supports_AB(Transport* transport) { return !get_suffixes(transport).empty(); } // Given a current slot, this returns what the 'other' slot is. static std::string get_other_slot(Transport* transport, std::string& current_slot) { static std::string get_other_slot(Transport* transport, const std::string& current_slot) { std::vector<std::string> suffixes = get_suffixes(transport); if (!suffixes.empty()) { Loading @@ -872,6 +891,12 @@ static std::string get_other_slot(Transport* transport, std::string& current_slo return ""; } static std::string get_other_slot(Transport* transport) { std::string current_slot; fb_getvar(transport, "current-slot", ¤t_slot); return get_other_slot(transport, current_slot); } static std::string verify_slot(Transport* transport, const char *slot, bool allow_all) { if (strcmp(slot, "all") == 0) { if (allow_all) { Loading Loading @@ -994,9 +1019,11 @@ static void do_update_signature(ZipArchiveHandle zip, char* fn) { // Sets slot_override as the active slot. If slot_override is blank, // set current slot as active instead. This clears slot-unbootable. static void set_active(Transport* transport, const char* slot_override) { if (slot_override && slot_override[0]) { fb_set_active(slot_override); static void set_active(Transport* transport, const std::string& slot_override) { if (!supports_AB(transport)) { return; } else if (slot_override != "") { fb_set_active(slot_override.c_str()); } else { std::string current_slot; if (fb_getvar(transport, "current-slot", ¤t_slot)) { Loading @@ -1006,7 +1033,7 @@ static void set_active(Transport* transport, const char* slot_override) { } } static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) { static void do_update(Transport* transport, const char* filename, const std::string& slot_override, bool erase_first) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); Loading @@ -1027,7 +1054,31 @@ static void do_update(Transport* transport, const char* filename, const char* sl setup_requirements(reinterpret_cast<char*>(data), sz); std::string secondary; bool update_secondary = slot_override != "all"; if (update_secondary) { if (slot_override != "") { secondary = get_other_slot(transport, slot_override); } else { secondary = get_other_slot(transport); } if (secondary == "") { if (supports_AB(transport)) { fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n"); } update_secondary = false; } } for (size_t i = 0; i < arraysize(images); ++i) { const char* slot = slot_override.c_str(); if (images[i].is_secondary) { if (update_secondary) { slot = secondary.c_str(); } else { continue; } } int fd = unzip_to_file(zip, images[i].img_name); if (fd == -1) { if (images[i].is_optional) { Loading @@ -1052,7 +1103,7 @@ static void do_update(Transport* transport, const char* filename, const char* sl * program exits. */ }; do_for_partitions(transport, images[i].part_name, slot_override, update, false); do_for_partitions(transport, images[i].part_name, slot, update, false); } CloseArchive(zip); Loading @@ -1076,26 +1127,50 @@ static void do_send_signature(const char* filename) { fb_queue_command("signature", "installing signature"); } static void do_flashall(Transport* transport, const char* slot_override, int erase_first) { static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool flash_primary, bool flash_secondary) { std::string fname; if (flash_primary) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); std::string fname = find_item("info", product); fname = find_item("info", product); if (fname.empty()) die("cannot find android-info.txt"); int64_t sz; void* data = load_file(fname, &sz); void* data = load_file(fname.c_str(), &sz); if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno)); setup_requirements(reinterpret_cast<char*>(data), sz); } std::string secondary; if (flash_secondary) { if (slot_override != "") { secondary = get_other_slot(transport, slot_override); } else { secondary = get_other_slot(transport); } if (secondary == "") { if (supports_AB(transport)) { fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n"); } flash_secondary = false; } } for (size_t i = 0; i < arraysize(images); i++) { fname = find_item(images[i].part_name, product); const char* slot = NULL; if (images[i].is_secondary) { if (flash_secondary) slot = secondary.c_str(); } else { if (flash_primary) slot = slot_override.c_str(); } if (!slot) continue; fname = find_item_given_name(images[i].img_name, product); fastboot_buffer buf; if (!load_buf(transport, fname.c_str(), &buf)) { if (load_buf(transport, fname.c_str(), &buf)) { if (images[i].is_optional) continue; die("could not load '%s': %s", images[i].img_name, strerror(errno)); die("could not load %s\n", images[i].img_name); } auto flashall = [&](const std::string &partition) { Loading @@ -1105,10 +1180,10 @@ static void do_flashall(Transport* transport, const char* slot_override, int era } flash_buf(partition.c_str(), &buf); }; do_for_partitions(transport, images[i].part_name, slot_override, flashall, false); do_for_partitions(transport, images[i].part_name, slot, flashall, false); } set_active(transport, slot_override); if (flash_primary) set_active(transport, slot_override); } #define skip(n) do { argc -= (n); argv += (n); } while (0) Loading Loading @@ -1435,10 +1510,8 @@ int main(int argc, char **argv) return 1; } if (slot_override != "") slot_override = verify_slot(transport, slot_override.c_str()); if (next_active != "") next_active = verify_slot(transport, next_active.c_str(), false); if (slot_override != "") slot_override = verify_slot(transport, slot_override.c_str()); if (next_active != "") next_active = verify_slot(transport, next_active.c_str(), false); if (wants_set_active) { if (next_active == "") { Loading Loading @@ -1599,14 +1672,27 @@ int main(int argc, char **argv) do_for_partitions(transport, argv[1], slot_override.c_str(), flashraw, true); } else if(!strcmp(*argv, "flashall")) { skip(1); do_flashall(transport, slot_override.c_str(), erase_first); if (slot_override == "all") { fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed."); do_flashall(transport, slot_override, erase_first, true, false); } else { do_flashall(transport, slot_override, erase_first, true, true); } wants_reboot = true; } else if(!strcmp(*argv, "flash-primary")) { skip(1); do_flashall(transport, slot_override, erase_first, true, false); wants_reboot = true; } else if(!strcmp(*argv, "flash-secondary")) { skip(1); do_flashall(transport, slot_override, erase_first, false, true); wants_reboot = true; } else if(!strcmp(*argv, "update")) { if (argc > 1) { do_update(transport, argv[1], slot_override.c_str(), erase_first); do_update(transport, argv[1], slot_override, erase_first); skip(2); } else { do_update(transport, "update.zip", slot_override.c_str(), erase_first); do_update(transport, "update.zip", slot_override, erase_first); skip(1); } wants_reboot = 1; Loading Loading
fastboot/fastboot.cpp +134 −48 Original line number Diff line number Diff line Loading @@ -99,19 +99,41 @@ struct fastboot_buffer { }; static struct { char img_name[13]; char sig_name[13]; char img_name[17]; char sig_name[17]; char part_name[9]; bool is_optional; bool is_secondary; } images[] = { {"boot.img", "boot.sig", "boot", false}, {"recovery.img", "recovery.sig", "recovery", true}, {"system.img", "system.sig", "system", false}, {"vendor.img", "vendor.sig", "vendor", true}, {"boot.img", "boot.sig", "boot", false, false}, {"boot_other.img", "boot.sig", "boot", true, true}, {"recovery.img", "recovery.sig", "recovery", true, false}, {"system.img", "system.sig", "system", false, false}, {"system_other.img", "system.sig", "system", true, true}, {"vendor.img", "vendor.sig", "vendor", true, false}, {"vendor_other.img", "vendor.sig", "vendor", true, true}, }; static std::string find_item(const char* item, const char* product) { static std::string find_item_given_name(const char* img_name, const char* product) { char *dir; if(product) { std::string path = get_my_path(); return android::base::StringPrintf("%s/../../../target/product/%s/%s", path.c_str(), product, img_name); } dir = getenv("ANDROID_PRODUCT_OUT"); if((dir == 0) || (dir[0] == 0)) { die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); } return android::base::StringPrintf("%s/%s", dir, img_name); } std::string find_item(const char* item, const char* product) { const char *fn; if(!strcmp(item,"boot")) { fn = "boot.img"; } else if(!strcmp(item,"recovery")) { Loading @@ -131,19 +153,7 @@ static std::string find_item(const char* item, const char* product) { return ""; } if (product) { std::string path = get_my_path(); path.erase(path.find_last_of('/')); return android::base::StringPrintf("%s/../../../target/product/%s/%s", path.c_str(), product, fn); } char* dir = getenv("ANDROID_PRODUCT_OUT"); if (dir == nullptr || dir[0] == '\0') { die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); } return android::base::StringPrintf("%s/%s", dir, fn); return find_item_given_name(fn, product); } static int64_t get_file_size(int fd) { Loading Loading @@ -314,6 +324,11 @@ static void usage() { " if found -- recovery. If the device\n" " supports slots, the slot that has\n" " been flashed to is set as active.\n" " Secondary images may be flashed to\n" " an inactive slot.\n" " flash-primary Same as flashall, but do not flash\n" " secondary images.\n" " flash-secondary Only flashes the secondary images.\n" " flash <partition> [ <filename> ] Write a file to a flash partition.\n" " flashing lock Locks the device. Prevents flashing.\n" " flashing unlock Unlocks the device. Allows flashing\n" Loading Loading @@ -858,8 +873,12 @@ static std::vector<std::string> get_suffixes(Transport* transport) { return suffixes; } static bool supports_AB(Transport* transport) { return !get_suffixes(transport).empty(); } // Given a current slot, this returns what the 'other' slot is. static std::string get_other_slot(Transport* transport, std::string& current_slot) { static std::string get_other_slot(Transport* transport, const std::string& current_slot) { std::vector<std::string> suffixes = get_suffixes(transport); if (!suffixes.empty()) { Loading @@ -872,6 +891,12 @@ static std::string get_other_slot(Transport* transport, std::string& current_slo return ""; } static std::string get_other_slot(Transport* transport) { std::string current_slot; fb_getvar(transport, "current-slot", ¤t_slot); return get_other_slot(transport, current_slot); } static std::string verify_slot(Transport* transport, const char *slot, bool allow_all) { if (strcmp(slot, "all") == 0) { if (allow_all) { Loading Loading @@ -994,9 +1019,11 @@ static void do_update_signature(ZipArchiveHandle zip, char* fn) { // Sets slot_override as the active slot. If slot_override is blank, // set current slot as active instead. This clears slot-unbootable. static void set_active(Transport* transport, const char* slot_override) { if (slot_override && slot_override[0]) { fb_set_active(slot_override); static void set_active(Transport* transport, const std::string& slot_override) { if (!supports_AB(transport)) { return; } else if (slot_override != "") { fb_set_active(slot_override.c_str()); } else { std::string current_slot; if (fb_getvar(transport, "current-slot", ¤t_slot)) { Loading @@ -1006,7 +1033,7 @@ static void set_active(Transport* transport, const char* slot_override) { } } static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) { static void do_update(Transport* transport, const char* filename, const std::string& slot_override, bool erase_first) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); Loading @@ -1027,7 +1054,31 @@ static void do_update(Transport* transport, const char* filename, const char* sl setup_requirements(reinterpret_cast<char*>(data), sz); std::string secondary; bool update_secondary = slot_override != "all"; if (update_secondary) { if (slot_override != "") { secondary = get_other_slot(transport, slot_override); } else { secondary = get_other_slot(transport); } if (secondary == "") { if (supports_AB(transport)) { fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n"); } update_secondary = false; } } for (size_t i = 0; i < arraysize(images); ++i) { const char* slot = slot_override.c_str(); if (images[i].is_secondary) { if (update_secondary) { slot = secondary.c_str(); } else { continue; } } int fd = unzip_to_file(zip, images[i].img_name); if (fd == -1) { if (images[i].is_optional) { Loading @@ -1052,7 +1103,7 @@ static void do_update(Transport* transport, const char* filename, const char* sl * program exits. */ }; do_for_partitions(transport, images[i].part_name, slot_override, update, false); do_for_partitions(transport, images[i].part_name, slot, update, false); } CloseArchive(zip); Loading @@ -1076,26 +1127,50 @@ static void do_send_signature(const char* filename) { fb_queue_command("signature", "installing signature"); } static void do_flashall(Transport* transport, const char* slot_override, int erase_first) { static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool flash_primary, bool flash_secondary) { std::string fname; if (flash_primary) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); std::string fname = find_item("info", product); fname = find_item("info", product); if (fname.empty()) die("cannot find android-info.txt"); int64_t sz; void* data = load_file(fname, &sz); void* data = load_file(fname.c_str(), &sz); if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno)); setup_requirements(reinterpret_cast<char*>(data), sz); } std::string secondary; if (flash_secondary) { if (slot_override != "") { secondary = get_other_slot(transport, slot_override); } else { secondary = get_other_slot(transport); } if (secondary == "") { if (supports_AB(transport)) { fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n"); } flash_secondary = false; } } for (size_t i = 0; i < arraysize(images); i++) { fname = find_item(images[i].part_name, product); const char* slot = NULL; if (images[i].is_secondary) { if (flash_secondary) slot = secondary.c_str(); } else { if (flash_primary) slot = slot_override.c_str(); } if (!slot) continue; fname = find_item_given_name(images[i].img_name, product); fastboot_buffer buf; if (!load_buf(transport, fname.c_str(), &buf)) { if (load_buf(transport, fname.c_str(), &buf)) { if (images[i].is_optional) continue; die("could not load '%s': %s", images[i].img_name, strerror(errno)); die("could not load %s\n", images[i].img_name); } auto flashall = [&](const std::string &partition) { Loading @@ -1105,10 +1180,10 @@ static void do_flashall(Transport* transport, const char* slot_override, int era } flash_buf(partition.c_str(), &buf); }; do_for_partitions(transport, images[i].part_name, slot_override, flashall, false); do_for_partitions(transport, images[i].part_name, slot, flashall, false); } set_active(transport, slot_override); if (flash_primary) set_active(transport, slot_override); } #define skip(n) do { argc -= (n); argv += (n); } while (0) Loading Loading @@ -1435,10 +1510,8 @@ int main(int argc, char **argv) return 1; } if (slot_override != "") slot_override = verify_slot(transport, slot_override.c_str()); if (next_active != "") next_active = verify_slot(transport, next_active.c_str(), false); if (slot_override != "") slot_override = verify_slot(transport, slot_override.c_str()); if (next_active != "") next_active = verify_slot(transport, next_active.c_str(), false); if (wants_set_active) { if (next_active == "") { Loading Loading @@ -1599,14 +1672,27 @@ int main(int argc, char **argv) do_for_partitions(transport, argv[1], slot_override.c_str(), flashraw, true); } else if(!strcmp(*argv, "flashall")) { skip(1); do_flashall(transport, slot_override.c_str(), erase_first); if (slot_override == "all") { fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed."); do_flashall(transport, slot_override, erase_first, true, false); } else { do_flashall(transport, slot_override, erase_first, true, true); } wants_reboot = true; } else if(!strcmp(*argv, "flash-primary")) { skip(1); do_flashall(transport, slot_override, erase_first, true, false); wants_reboot = true; } else if(!strcmp(*argv, "flash-secondary")) { skip(1); do_flashall(transport, slot_override, erase_first, false, true); wants_reboot = true; } else if(!strcmp(*argv, "update")) { if (argc > 1) { do_update(transport, argv[1], slot_override.c_str(), erase_first); do_update(transport, argv[1], slot_override, erase_first); skip(2); } else { do_update(transport, "update.zip", slot_override.c_str(), erase_first); do_update(transport, "update.zip", slot_override, erase_first); skip(1); } wants_reboot = 1; Loading