Loading fastboot/fastboot.cpp +80 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,8 @@ static int show_help() { " set_active SLOT Set the active slot.\n" " oem [COMMAND...] Execute OEM-specific command.\n" " gsi wipe|disable Wipe or disable a GSI installation (fastbootd only).\n" " wipe-super [SUPER_EMPTY] Wipe the super partition. This will reset it to\n" " contain an empty set of default dynamic partitions.\n" "\n" "boot image:\n" " boot KERNEL [RAMDISK [SECOND]]\n" Loading Loading @@ -1582,6 +1584,76 @@ static bool should_flash_in_userspace(const std::string& partition_name) { return false; } static bool wipe_super(const android::fs_mgr::LpMetadata& metadata, const std::string& slot, std::string* message) { auto super_device = GetMetadataSuperBlockDevice(metadata); auto block_size = metadata.geometry.logical_block_size; auto super_bdev_name = android::fs_mgr::GetBlockDevicePartitionName(*super_device); if (super_bdev_name != "super") { // retrofit devices do not allow flashing to the retrofit partitions, // so enable it if we can. fb->RawCommand("oem allow-flash-super"); } // Note: do not use die() in here, since we want TemporaryDir's destructor // to be called. TemporaryDir temp_dir; bool ok; if (metadata.block_devices.size() > 1) { ok = WriteSplitImageFiles(temp_dir.path, metadata, block_size, {}, true); } else { auto image_path = temp_dir.path + "/"s + super_bdev_name + ".img"; ok = WriteToImageFile(image_path, metadata, block_size, {}, true); } if (!ok) { *message = "Could not generate a flashable super image file"; return false; } for (const auto& block_device : metadata.block_devices) { auto partition = android::fs_mgr::GetBlockDevicePartitionName(block_device); bool force_slot = !!(block_device.flags & LP_BLOCK_DEVICE_SLOT_SUFFIXED); std::string image_name; if (metadata.block_devices.size() > 1) { image_name = "super_" + partition + ".img"; } else { image_name = partition + ".img"; } auto image_path = temp_dir.path + "/"s + image_name; auto flash = [&](const std::string& partition_name) { do_flash(partition_name.c_str(), image_path.c_str()); }; do_for_partitions(partition, slot, flash, force_slot); unlink(image_path.c_str()); } return true; } static void do_wipe_super(const std::string& image, const std::string& slot_override) { if (access(image.c_str(), R_OK) != 0) { die("Could not read image: %s", image.c_str()); } auto metadata = android::fs_mgr::ReadFromImageFile(image); if (!metadata) { die("Could not parse image: %s", image.c_str()); } auto slot = slot_override; if (slot.empty()) { slot = get_current_slot(); } std::string message; if (!wipe_super(*metadata.get(), slot, &message)) { die(message); } } int FastBootTool::Main(int argc, char* argv[]) { bool wants_wipe = false; bool wants_reboot = false; Loading Loading @@ -1958,6 +2030,14 @@ int FastBootTool::Main(int argc, char* argv[]) { } else { syntax_error("expected 'wipe' or 'disable'"); } } else if (command == "wipe-super") { std::string image; if (args.empty()) { image = find_item_given_name("super_empty.img"); } else { image = next_arg(&args); } do_wipe_super(image, slot_override); } else { syntax_error("unknown command %s", command.c_str()); } Loading fastboot/util.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ void die(const char* fmt, ...) { exit(EXIT_FAILURE); } void die(const std::string& str) { die("%s", str.c_str()); } void set_verbose() { g_verbose = true; } Loading fastboot/util.h +3 −0 Original line number Diff line number Diff line Loading @@ -15,4 +15,7 @@ void set_verbose(); // use the same attribute for compile-time format string checking. void die(const char* fmt, ...) __attribute__((__noreturn__)) __attribute__((__format__(__printf__, 1, 2))); void verbose(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2))); void die(const std::string& str) __attribute__((__noreturn__)); Loading
fastboot/fastboot.cpp +80 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,8 @@ static int show_help() { " set_active SLOT Set the active slot.\n" " oem [COMMAND...] Execute OEM-specific command.\n" " gsi wipe|disable Wipe or disable a GSI installation (fastbootd only).\n" " wipe-super [SUPER_EMPTY] Wipe the super partition. This will reset it to\n" " contain an empty set of default dynamic partitions.\n" "\n" "boot image:\n" " boot KERNEL [RAMDISK [SECOND]]\n" Loading Loading @@ -1582,6 +1584,76 @@ static bool should_flash_in_userspace(const std::string& partition_name) { return false; } static bool wipe_super(const android::fs_mgr::LpMetadata& metadata, const std::string& slot, std::string* message) { auto super_device = GetMetadataSuperBlockDevice(metadata); auto block_size = metadata.geometry.logical_block_size; auto super_bdev_name = android::fs_mgr::GetBlockDevicePartitionName(*super_device); if (super_bdev_name != "super") { // retrofit devices do not allow flashing to the retrofit partitions, // so enable it if we can. fb->RawCommand("oem allow-flash-super"); } // Note: do not use die() in here, since we want TemporaryDir's destructor // to be called. TemporaryDir temp_dir; bool ok; if (metadata.block_devices.size() > 1) { ok = WriteSplitImageFiles(temp_dir.path, metadata, block_size, {}, true); } else { auto image_path = temp_dir.path + "/"s + super_bdev_name + ".img"; ok = WriteToImageFile(image_path, metadata, block_size, {}, true); } if (!ok) { *message = "Could not generate a flashable super image file"; return false; } for (const auto& block_device : metadata.block_devices) { auto partition = android::fs_mgr::GetBlockDevicePartitionName(block_device); bool force_slot = !!(block_device.flags & LP_BLOCK_DEVICE_SLOT_SUFFIXED); std::string image_name; if (metadata.block_devices.size() > 1) { image_name = "super_" + partition + ".img"; } else { image_name = partition + ".img"; } auto image_path = temp_dir.path + "/"s + image_name; auto flash = [&](const std::string& partition_name) { do_flash(partition_name.c_str(), image_path.c_str()); }; do_for_partitions(partition, slot, flash, force_slot); unlink(image_path.c_str()); } return true; } static void do_wipe_super(const std::string& image, const std::string& slot_override) { if (access(image.c_str(), R_OK) != 0) { die("Could not read image: %s", image.c_str()); } auto metadata = android::fs_mgr::ReadFromImageFile(image); if (!metadata) { die("Could not parse image: %s", image.c_str()); } auto slot = slot_override; if (slot.empty()) { slot = get_current_slot(); } std::string message; if (!wipe_super(*metadata.get(), slot, &message)) { die(message); } } int FastBootTool::Main(int argc, char* argv[]) { bool wants_wipe = false; bool wants_reboot = false; Loading Loading @@ -1958,6 +2030,14 @@ int FastBootTool::Main(int argc, char* argv[]) { } else { syntax_error("expected 'wipe' or 'disable'"); } } else if (command == "wipe-super") { std::string image; if (args.empty()) { image = find_item_given_name("super_empty.img"); } else { image = next_arg(&args); } do_wipe_super(image, slot_override); } else { syntax_error("unknown command %s", command.c_str()); } Loading
fastboot/util.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ void die(const char* fmt, ...) { exit(EXIT_FAILURE); } void die(const std::string& str) { die("%s", str.c_str()); } void set_verbose() { g_verbose = true; } Loading
fastboot/util.h +3 −0 Original line number Diff line number Diff line Loading @@ -15,4 +15,7 @@ void set_verbose(); // use the same attribute for compile-time format string checking. void die(const char* fmt, ...) __attribute__((__noreturn__)) __attribute__((__format__(__printf__, 1, 2))); void verbose(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2))); void die(const std::string& str) __attribute__((__noreturn__));