Loading fastboot/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -207,7 +207,6 @@ cc_library_host_static { cpp_std: "c++17", srcs: [ "bootimg_utils.cpp", "engine.cpp", "fastboot.cpp", "fs.cpp", "socket.cpp", Loading fastboot/engine.cppdeleted 100644 → 0 +0 −197 Original line number Diff line number Diff line /* * Copyright (C) 2008 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "engine.h" #include <errno.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <memory> #include <vector> #include <android-base/stringprintf.h> #include "constants.h" #include "transport.h" using android::base::StringPrintf; static fastboot::FastBootDriver* fb = nullptr; void fb_init(fastboot::FastBootDriver& fbi) { fb = &fbi; auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); }; fb->SetInfoCallback(cb); } void fb_reinit(Transport* transport) { if (Transport* old_transport = fb->set_transport(transport)) { delete old_transport; } } const std::string fb_get_error() { return fb->Error(); } bool fb_getvar(const std::string& key, std::string* value) { return !fb->GetVar(key, value); } static void HandleResult(double start, int status) { if (status) { fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); die("Command failed"); } else { double split = now(); fprintf(stderr, "OKAY [%7.3fs]\n", (split - start)); } } #define RUN_COMMAND(command) \ { \ double start = now(); \ auto status = (command); \ HandleResult(start, status); \ } void fb_set_active(const std::string& slot) { Status("Setting current slot to '" + slot + "'"); RUN_COMMAND(fb->SetActive(slot)); } void fb_erase(const std::string& partition) { Status("Erasing '" + partition + "'"); RUN_COMMAND(fb->Erase(partition)); } void fb_flash_fd(const std::string& partition, int fd, uint32_t sz) { Status(StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024)); RUN_COMMAND(fb->Download(fd, sz)); Status("Writing '" + partition + "'"); RUN_COMMAND(fb->Flash(partition)); } void fb_flash(const std::string& partition, const std::vector<char>& data) { Status(StringPrintf("Sending '%s' (%zu KB)", partition.c_str(), data.size() / 1024)); RUN_COMMAND(fb->Download(data)); Status("Writing '" + partition + "'"); RUN_COMMAND(fb->Flash(partition)); } void fb_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz, size_t current, size_t total) { Status(StringPrintf("Sending sparse '%s' %zu/%zu (%u KB)", partition.c_str(), current, total, sz / 1024)); RUN_COMMAND(fb->Download(s)); Status(StringPrintf("Writing sparse '%s' %zu/%zu", partition.c_str(), current, total)); RUN_COMMAND(fb->Flash(partition)); } void fb_create_partition(const std::string& partition, const std::string& size) { Status("Creating '" + partition + "'"); RUN_COMMAND(fb->RawCommand(FB_CMD_CREATE_PARTITION ":" + partition + ":" + size)); } void fb_delete_partition(const std::string& partition) { Status("Deleting '" + partition + "'"); RUN_COMMAND(fb->RawCommand(FB_CMD_DELETE_PARTITION ":" + partition)); } void fb_resize_partition(const std::string& partition, const std::string& size) { Status("Resizing '" + partition + "'"); RUN_COMMAND(fb->RawCommand(FB_CMD_RESIZE_PARTITION ":" + partition + ":" + size)); } void fb_display(const std::string& label, const std::string& var) { std::string value; auto status = fb->GetVar(var, &value); if (status) { fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str()); return; } fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str()); } void fb_reboot() { fprintf(stderr, "Rebooting"); fb->Reboot(); fprintf(stderr, "\n"); } void fb_command(const std::string& cmd, const std::string& msg) { Status(msg); RUN_COMMAND(fb->RawCommand(cmd)); } void fb_download(const std::string& name, const std::vector<char>& data) { Status("Downloading '" + name + "'"); RUN_COMMAND(fb->Download(data)); } void fb_download_fd(const std::string& name, int fd, uint32_t sz) { Status(StringPrintf("Sending '%s' (%u KB)", name.c_str(), sz / 1024)); RUN_COMMAND(fb->Download(fd, sz)); } void fb_upload(const std::string& outfile) { Status("Uploading '" + outfile + "'"); RUN_COMMAND(fb->Upload(outfile)); } void fb_notice(const std::string& notice) { Status(notice); fprintf(stderr, "\n"); } void fb_wait_for_disconnect() { fb->WaitForDisconnect(); } bool fb_reboot_to_userspace() { Status("Rebooting to userspace fastboot"); verbose("\n"); if (fb->RebootTo("fastboot") != fastboot::RetCode::SUCCESS) { fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); return false; } fprintf(stderr, "OKAY\n"); fb_reinit(nullptr); return true; } fastboot/fastboot.cpp +122 −78 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ * SUCH DAMAGE. */ #include "fastboot.h" #include <ctype.h> #include <errno.h> #include <fcntl.h> Loading Loading @@ -63,12 +65,13 @@ #include "bootimg_utils.h" #include "diagnose_usb.h" #include "engine.h" #include "fastboot_driver.h" #include "fs.h" #include "tcp.h" #include "transport.h" #include "udp.h" #include "usb.h" #include "util.h" using android::base::ReadFully; using android::base::Split; Loading Loading @@ -98,6 +101,8 @@ static bool g_disable_verification = false; static const std::string convert_fbe_marker_filename("convert_fbe"); fastboot::FastBootDriver* fb = nullptr; enum fb_buffer_type { FB_BUFFER_FD, FB_BUFFER_SPARSE, Loading Loading @@ -179,6 +184,28 @@ static std::string find_item(const std::string& item) { return ""; } double last_start_time; static void Status(const std::string& message) { static constexpr char kStatusFormat[] = "%-50s "; fprintf(stderr, kStatusFormat, message.c_str()); last_start_time = now(); } static void Epilog(int status) { if (status) { fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); die("Command failed"); } else { double split = now(); fprintf(stderr, "OKAY [%7.3fs]\n", (split - last_start_time)); } } static void InfoMessage(const std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); } static int64_t get_file_size(int fd) { struct stat sb; if (fstat(fd, &sb) == -1) { Loading Loading @@ -606,9 +633,10 @@ static void CheckRequirement(const std::string& cur_product, const std::string& } std::string var_value; if (!fb_getvar(var, &var_value)) { if (fb->GetVar(var, &var_value) != fastboot::SUCCESS) { fprintf(stderr, "FAILED\n\n"); fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb_get_error().c_str()); fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb->Error().c_str()); die("requirements not met!"); } Loading Loading @@ -686,7 +714,7 @@ bool ParseRequirementLine(const std::string& line, std::string* name, std::strin static void HandlePartitionExists(const std::vector<std::string>& options) { const std::string& partition_name = options[0]; std::string has_slot; if (!fb_getvar("has-slot:" + partition_name, &has_slot) || if (fb->GetVar("has-slot:" + partition_name, &has_slot) != fastboot::SUCCESS || (has_slot != "yes" && has_slot != "no")) { die("device doesn't have required partition %s!", partition_name.c_str()); } Loading @@ -705,8 +733,8 @@ static void HandlePartitionExists(const std::vector<std::string>& options) { static void CheckRequirements(const std::string& data) { std::string cur_product; if (!fb_getvar("product", &cur_product)) { fprintf(stderr, "getvar:product FAILED (%s)\n", fb_get_error().c_str()); if (fb->GetVar("product", &cur_product) != fastboot::SUCCESS) { fprintf(stderr, "getvar:product FAILED (%s)\n", fb->Error().c_str()); } auto lines = Split(data, "\n"); Loading @@ -732,12 +760,24 @@ static void CheckRequirements(const std::string& data) { } } static void dump_info() { fb_notice("--------------------------------------------"); fb_display("Bootloader Version...", "version-bootloader"); fb_display("Baseband Version.....", "version-baseband"); fb_display("Serial Number........", "serialno"); fb_notice("--------------------------------------------"); static void DisplayVarOrError(const std::string& label, const std::string& var) { std::string value; if (fb->GetVar(var, &value) != fastboot::SUCCESS) { Status("getvar:" + var); fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); return; } fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str()); } static void DumpInfo() { fprintf(stderr, "--------------------------------------------\n"); DisplayVarOrError("Bootloader Version...", "version-bootloader"); DisplayVarOrError("Baseband Version.....", "version-baseband"); DisplayVarOrError("Serial Number........", "serialno"); fprintf(stderr, "--------------------------------------------\n"); } static struct sparse_file** load_sparse_files(int fd, int64_t max_size) { Loading @@ -762,7 +802,7 @@ static struct sparse_file** load_sparse_files(int fd, int64_t max_size) { static int64_t get_target_sparse_limit() { std::string max_download_size; if (!fb_getvar("max-download-size", &max_download_size) || if (fb->GetVar("max-download-size", &max_download_size) != fastboot::SUCCESS || max_download_size.empty()) { verbose("target didn't report max-download-size"); return 0; Loading Loading @@ -910,12 +950,12 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf) for (size_t i = 0; i < sparse_files.size(); ++i) { const auto& pair = sparse_files[i]; fb_flash_sparse(partition, pair.first, pair.second, i + 1, sparse_files.size()); fb->FlashPartition(partition, pair.first, pair.second, i + 1, sparse_files.size()); } break; } case FB_BUFFER_FD: fb_flash_fd(partition, buf->fd, buf->sz); fb->FlashPartition(partition, buf->fd, buf->sz); break; default: die("unknown buffer type: %d", buf->type); Loading @@ -924,14 +964,15 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf) static std::string get_current_slot() { std::string current_slot; if (!fb_getvar("current-slot", ¤t_slot)) return ""; if (fb->GetVar("current-slot", ¤t_slot) != fastboot::SUCCESS) return ""; return current_slot; } static int get_slot_count() { std::string var; int count = 0; if (!fb_getvar("slot-count", &var) || !android::base::ParseInt(var, &count)) { if (fb->GetVar("slot-count", &var) != fastboot::SUCCESS || !android::base::ParseInt(var, &count)) { return 0; } return count; Loading Loading @@ -1006,7 +1047,7 @@ static void do_for_partition(const std::string& part, const std::string& slot, std::string has_slot; std::string current_slot; if (!fb_getvar("has-slot:" + part, &has_slot)) { if (fb->GetVar("has-slot:" + part, &has_slot) != fastboot::SUCCESS) { /* If has-slot is not supported, the answer is no. */ has_slot = "no"; } Loading Loading @@ -1039,7 +1080,7 @@ static void do_for_partitions(const std::string& part, const std::string& slot, std::string has_slot; if (slot == "all") { if (!fb_getvar("has-slot:" + part, &has_slot)) { if (fb->GetVar("has-slot:" + part, &has_slot) != fastboot::SUCCESS) { die("Could not check if partition %s has slot %s", part.c_str(), slot.c_str()); } if (has_slot == "yes") { Loading Loading @@ -1069,25 +1110,25 @@ static void set_active(const std::string& slot_override) { if (!supports_AB()) return; if (slot_override != "") { fb_set_active(slot_override); fb->SetActive(slot_override); } else { std::string current_slot = get_current_slot(); if (current_slot != "") { fb_set_active(current_slot); fb->SetActive(current_slot); } } } static bool is_userspace_fastboot() { std::string value; return fb_getvar("is-userspace", &value) && value == "yes"; return fb->GetVar("is-userspace", &value) == fastboot::SUCCESS && value == "yes"; } static bool if_partition_exists(const std::string& partition, const std::string& slot) { std::string has_slot; std::string partition_name = partition; if (fb_getvar("has-slot:" + partition, &has_slot) && has_slot == "yes") { if (fb->GetVar("has-slot:" + partition, &has_slot) == fastboot::SUCCESS && has_slot == "yes") { if (slot == "") { std::string current_slot = get_current_slot(); if (current_slot == "") { Loading @@ -1099,23 +1140,24 @@ static bool if_partition_exists(const std::string& partition, const std::string& } } std::string partition_size; return fb_getvar("partition-size:" + partition_name, &partition_size); return fb->GetVar("partition-size:" + partition_name, &partition_size) == fastboot::SUCCESS; } static bool is_logical(const std::string& partition) { std::string value; return fb_getvar("is-logical:" + partition, &value) && value == "yes"; return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes"; } static void reboot_to_userspace_fastboot() { if (!fb_reboot_to_userspace()) { die("Must reboot to userspace fastboot to flash logical partitions"); } fb->RebootTo("fastboot"); auto* old_transport = fb->set_transport(nullptr); delete old_transport; // Give the current connection time to close. std::this_thread::sleep_for(std::chrono::milliseconds(1000)); fb_reinit(open_device()); fb->set_transport(open_device()); } class ImageSource { Loading Loading @@ -1156,6 +1198,7 @@ FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_ov } void FlashAllTool::Flash() { DumpInfo(); CheckRequirements(); DetermineSecondarySlot(); CollectImages(); Loading @@ -1172,7 +1215,7 @@ void FlashAllTool::Flash() { for (const auto& [image, slot] : os_images_) { auto resize_partition = [](const std::string& partition) -> void { if (is_logical(partition)) { fb_resize_partition(partition, "0"); fb->ResizePartition(partition, "0"); } }; do_for_partitions(image->part_name, slot, resize_partition, false); Loading Loading @@ -1248,12 +1291,12 @@ void FlashAllTool::FlashImage(const Image& image, const std::string& slot, fastb auto flash = [&, this](const std::string& partition_name) { std::vector<char> signature_data; if (source_.ReadFile(image.sig_name, &signature_data)) { fb_download("signature", signature_data); fb_command("signature", "installing signature"); fb->Download("signature", signature_data); fb->RawCommand("signature", "installing signature"); } if (is_logical(partition_name)) { fb_resize_partition(partition_name, std::to_string(buf->image_size)); fb->ResizePartition(partition_name, std::to_string(buf->image_size)); } flash_buf(partition_name.c_str(), buf); }; Loading @@ -1272,13 +1315,13 @@ void FlashAllTool::UpdateSuperPartition() { if (!is_userspace_fastboot()) { reboot_to_userspace_fastboot(); } fb_download_fd("super", fd, get_file_size(fd)); fb->Download("super", fd, get_file_size(fd)); std::string command = "update-super:super"; if (wipe_) { command += ":wipe"; } fb_command(command, "Updating super partition"); fb->RawCommand(command, "Updating super partition"); } class ZipImageSource final : public ImageSource { Loading @@ -1300,8 +1343,6 @@ int ZipImageSource::OpenFile(const std::string& name) const { } static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary) { dump_info(); ZipArchiveHandle zip; int error = OpenArchive(filename, &zip); if (error != 0) { Loading Loading @@ -1334,9 +1375,6 @@ int LocalImageSource::OpenFile(const std::string& name) const { } static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) { std::string fname; dump_info(); FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe); tool.Flash(); } Loading @@ -1355,7 +1393,7 @@ static void do_oem_command(const std::string& cmd, std::vector<std::string>* arg while (!args->empty()) { command += " " + next_arg(args); } fb_command(command, ""); fb->RawCommand(command, ""); } static std::string fb_fix_numeric_var(std::string var) { Loading @@ -1369,7 +1407,7 @@ static std::string fb_fix_numeric_var(std::string var) { static unsigned fb_get_flash_block_size(std::string name) { std::string sizeString; if (!fb_getvar(name, &sizeString) || sizeString.empty()) { if (fb->GetVar(name, &sizeString) != fastboot::SUCCESS || sizeString.empty()) { // This device does not report flash block sizes, so return 0. return 0; } Loading Loading @@ -1407,7 +1445,7 @@ static void fb_perform_format( limit = sparse_limit; } if (!fb_getvar("partition-type:" + partition, &partition_type)) { if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) { errMsg = "Can't determine partition type.\n"; goto failed; } Loading @@ -1419,7 +1457,7 @@ static void fb_perform_format( partition_type = type_override; } if (!fb_getvar("partition-size:" + partition, &partition_size)) { if (fb->GetVar("partition-size:" + partition, &partition_size) != fastboot::SUCCESS) { errMsg = "Unable to get partition size\n"; goto failed; } Loading Loading @@ -1477,7 +1515,7 @@ failed: fprintf(stderr, "Erase successful, but not automatically formatting.\n"); if (errMsg) fprintf(stderr, "%s", errMsg); } fprintf(stderr, "FAILED (%s)\n", fb_get_error().c_str()); fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); } int FastBootTool::Main(int argc, char* argv[]) { Loading Loading @@ -1627,8 +1665,13 @@ int FastBootTool::Main(int argc, char* argv[]) { if (transport == nullptr) { return 1; } fastboot::FastBootDriver fb(transport); fb_init(fb); fastboot::DriverCallbacks driver_callbacks = { .prolog = Status, .epilog = Epilog, .info = InfoMessage, }; fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fb = &fastboot_driver; const double start = now(); Loading @@ -1639,7 +1682,7 @@ int FastBootTool::Main(int argc, char* argv[]) { if (next_active == "") { if (slot_override == "") { std::string current_slot; if (fb_getvar("current-slot", ¤t_slot)) { if (fb->GetVar("current-slot", ¤t_slot) == fastboot::SUCCESS) { next_active = verify_slot(current_slot, false); } else { wants_set_active = false; Loading @@ -1656,19 +1699,18 @@ int FastBootTool::Main(int argc, char* argv[]) { if (command == "getvar") { std::string variable = next_arg(&args); fb_display(variable, variable); DisplayVarOrError(variable, variable); } else if (command == "erase") { std::string partition = next_arg(&args); auto erase = [&](const std::string& partition) { std::string partition_type; if (fb_getvar(std::string("partition-type:") + partition, &partition_type) && if (fb->GetVar("partition-type:" + partition, &partition_type) == fastboot::SUCCESS && fs_get_generator(partition_type) != nullptr) { fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n", partition_type.c_str()); } fb_erase(partition); fb->Erase(partition); }; do_for_partitions(partition, slot_override, erase, true); } else if (android::base::StartsWith(command, "format")) { Loading Loading @@ -1698,8 +1740,8 @@ int FastBootTool::Main(int argc, char* argv[]) { die("could not load '%s': %s", filename.c_str(), strerror(errno)); } if (data.size() != 256) die("signature must be 256 bytes (got %zu)", data.size()); fb_download("signature", data); fb_command("signature", "installing signature"); fb->Download("signature", data); fb->RawCommand("signature", "installing signature"); } else if (command == "reboot") { wants_reboot = true; Loading Loading @@ -1727,7 +1769,7 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "reboot-fastboot") { wants_reboot_fastboot = true; } else if (command == "continue") { fb_command("continue", "resuming boot"); fb->Continue(); } else if (command == "boot") { std::string kernel = next_arg(&args); std::string ramdisk; Loading @@ -1736,8 +1778,8 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!args.empty()) second_stage = next_arg(&args); auto data = LoadBootableImage(kernel, ramdisk, second_stage); fb_download("boot.img", data); fb_command("boot", "booting"); fb->Download("boot.img", data); fb->Boot(); } else if (command == "flash") { std::string pname = next_arg(&args); Loading @@ -1763,7 +1805,7 @@ int FastBootTool::Main(int argc, char* argv[]) { auto data = LoadBootableImage(kernel, ramdisk, second_stage); auto flashraw = [&data](const std::string& partition) { fb_flash(partition, data); fb->FlashPartition(partition, data); }; do_for_partitions(partition, slot_override, flashraw, true); } else if (command == "flashall") { Loading @@ -1787,7 +1829,7 @@ int FastBootTool::Main(int argc, char* argv[]) { wants_reboot = true; } else if (command == "set_active") { std::string slot = verify_slot(next_arg(&args), false); fb_set_active(slot); fb->SetActive(slot); } else if (command == "stage") { std::string filename = next_arg(&args); Loading @@ -1795,10 +1837,10 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!load_buf(filename.c_str(), &buf) || buf.type != FB_BUFFER_FD) { die("cannot load '%s'", filename.c_str()); } fb_download_fd(filename, buf.fd, buf.sz); fb->Download(filename, buf.fd, buf.sz); } else if (command == "get_staged") { std::string filename = next_arg(&args); fb_upload(filename); fb->Upload(filename); } else if (command == "oem") { do_oem_command("oem", &args); } else if (command == "flashing") { Loading @@ -1815,14 +1857,14 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "create-logical-partition") { std::string partition = next_arg(&args); std::string size = next_arg(&args); fb_create_partition(partition, size); fb->CreatePartition(partition, size); } else if (command == "delete-logical-partition") { std::string partition = next_arg(&args); fb_delete_partition(partition); fb->DeletePartition(partition); } else if (command == "resize-logical-partition") { std::string partition = next_arg(&args); std::string size = next_arg(&args); fb_resize_partition(partition, size); fb->ResizePartition(partition, size); } else { syntax_error("unknown command %s", command.c_str()); } Loading @@ -1832,9 +1874,11 @@ int FastBootTool::Main(int argc, char* argv[]) { std::vector<std::string> partitions = { "userdata", "cache", "metadata" }; for (const auto& partition : partitions) { std::string partition_type; if (!fb_getvar(std::string{"partition-type:"} + partition, &partition_type)) continue; if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) { continue; } if (partition_type.empty()) continue; fb_erase(partition); fb->Erase(partition); if (partition == "userdata" && set_fbe_marker) { fprintf(stderr, "setting FBE marker on initial userdata...\n"); std::string initial_userdata_dir = create_fbemarker_tmpdir(); Loading @@ -1846,27 +1890,27 @@ int FastBootTool::Main(int argc, char* argv[]) { } } if (wants_set_active) { fb_set_active(next_active); fb->SetActive(next_active); } if (wants_reboot && !skip_reboot) { fb_reboot(); fb_wait_for_disconnect(); fb->Reboot(); fb->WaitForDisconnect(); } else if (wants_reboot_bootloader) { fb_command("reboot-bootloader", "rebooting into bootloader"); fb_wait_for_disconnect(); fb->RebootTo("bootloader"); fb->WaitForDisconnect(); } else if (wants_reboot_recovery) { fb_command("reboot-recovery", "rebooting into recovery"); fb_wait_for_disconnect(); fb->RebootTo("recovery"); fb->WaitForDisconnect(); } else if (wants_reboot_fastboot) { fb_command("reboot-fastboot", "rebooting into fastboot"); fb_wait_for_disconnect(); fb->RebootTo("fastboot"); fb->WaitForDisconnect(); } fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start)); if (Transport* old_transport = fb.set_transport(nullptr)) { auto* old_transport = fb->set_transport(nullptr); delete old_transport; } return 0; } Loading Loading
fastboot/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -207,7 +207,6 @@ cc_library_host_static { cpp_std: "c++17", srcs: [ "bootimg_utils.cpp", "engine.cpp", "fastboot.cpp", "fs.cpp", "socket.cpp", Loading
fastboot/engine.cppdeleted 100644 → 0 +0 −197 Original line number Diff line number Diff line /* * Copyright (C) 2008 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "engine.h" #include <errno.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <memory> #include <vector> #include <android-base/stringprintf.h> #include "constants.h" #include "transport.h" using android::base::StringPrintf; static fastboot::FastBootDriver* fb = nullptr; void fb_init(fastboot::FastBootDriver& fbi) { fb = &fbi; auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); }; fb->SetInfoCallback(cb); } void fb_reinit(Transport* transport) { if (Transport* old_transport = fb->set_transport(transport)) { delete old_transport; } } const std::string fb_get_error() { return fb->Error(); } bool fb_getvar(const std::string& key, std::string* value) { return !fb->GetVar(key, value); } static void HandleResult(double start, int status) { if (status) { fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); die("Command failed"); } else { double split = now(); fprintf(stderr, "OKAY [%7.3fs]\n", (split - start)); } } #define RUN_COMMAND(command) \ { \ double start = now(); \ auto status = (command); \ HandleResult(start, status); \ } void fb_set_active(const std::string& slot) { Status("Setting current slot to '" + slot + "'"); RUN_COMMAND(fb->SetActive(slot)); } void fb_erase(const std::string& partition) { Status("Erasing '" + partition + "'"); RUN_COMMAND(fb->Erase(partition)); } void fb_flash_fd(const std::string& partition, int fd, uint32_t sz) { Status(StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024)); RUN_COMMAND(fb->Download(fd, sz)); Status("Writing '" + partition + "'"); RUN_COMMAND(fb->Flash(partition)); } void fb_flash(const std::string& partition, const std::vector<char>& data) { Status(StringPrintf("Sending '%s' (%zu KB)", partition.c_str(), data.size() / 1024)); RUN_COMMAND(fb->Download(data)); Status("Writing '" + partition + "'"); RUN_COMMAND(fb->Flash(partition)); } void fb_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz, size_t current, size_t total) { Status(StringPrintf("Sending sparse '%s' %zu/%zu (%u KB)", partition.c_str(), current, total, sz / 1024)); RUN_COMMAND(fb->Download(s)); Status(StringPrintf("Writing sparse '%s' %zu/%zu", partition.c_str(), current, total)); RUN_COMMAND(fb->Flash(partition)); } void fb_create_partition(const std::string& partition, const std::string& size) { Status("Creating '" + partition + "'"); RUN_COMMAND(fb->RawCommand(FB_CMD_CREATE_PARTITION ":" + partition + ":" + size)); } void fb_delete_partition(const std::string& partition) { Status("Deleting '" + partition + "'"); RUN_COMMAND(fb->RawCommand(FB_CMD_DELETE_PARTITION ":" + partition)); } void fb_resize_partition(const std::string& partition, const std::string& size) { Status("Resizing '" + partition + "'"); RUN_COMMAND(fb->RawCommand(FB_CMD_RESIZE_PARTITION ":" + partition + ":" + size)); } void fb_display(const std::string& label, const std::string& var) { std::string value; auto status = fb->GetVar(var, &value); if (status) { fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str()); return; } fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str()); } void fb_reboot() { fprintf(stderr, "Rebooting"); fb->Reboot(); fprintf(stderr, "\n"); } void fb_command(const std::string& cmd, const std::string& msg) { Status(msg); RUN_COMMAND(fb->RawCommand(cmd)); } void fb_download(const std::string& name, const std::vector<char>& data) { Status("Downloading '" + name + "'"); RUN_COMMAND(fb->Download(data)); } void fb_download_fd(const std::string& name, int fd, uint32_t sz) { Status(StringPrintf("Sending '%s' (%u KB)", name.c_str(), sz / 1024)); RUN_COMMAND(fb->Download(fd, sz)); } void fb_upload(const std::string& outfile) { Status("Uploading '" + outfile + "'"); RUN_COMMAND(fb->Upload(outfile)); } void fb_notice(const std::string& notice) { Status(notice); fprintf(stderr, "\n"); } void fb_wait_for_disconnect() { fb->WaitForDisconnect(); } bool fb_reboot_to_userspace() { Status("Rebooting to userspace fastboot"); verbose("\n"); if (fb->RebootTo("fastboot") != fastboot::RetCode::SUCCESS) { fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); return false; } fprintf(stderr, "OKAY\n"); fb_reinit(nullptr); return true; }
fastboot/fastboot.cpp +122 −78 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ * SUCH DAMAGE. */ #include "fastboot.h" #include <ctype.h> #include <errno.h> #include <fcntl.h> Loading Loading @@ -63,12 +65,13 @@ #include "bootimg_utils.h" #include "diagnose_usb.h" #include "engine.h" #include "fastboot_driver.h" #include "fs.h" #include "tcp.h" #include "transport.h" #include "udp.h" #include "usb.h" #include "util.h" using android::base::ReadFully; using android::base::Split; Loading Loading @@ -98,6 +101,8 @@ static bool g_disable_verification = false; static const std::string convert_fbe_marker_filename("convert_fbe"); fastboot::FastBootDriver* fb = nullptr; enum fb_buffer_type { FB_BUFFER_FD, FB_BUFFER_SPARSE, Loading Loading @@ -179,6 +184,28 @@ static std::string find_item(const std::string& item) { return ""; } double last_start_time; static void Status(const std::string& message) { static constexpr char kStatusFormat[] = "%-50s "; fprintf(stderr, kStatusFormat, message.c_str()); last_start_time = now(); } static void Epilog(int status) { if (status) { fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); die("Command failed"); } else { double split = now(); fprintf(stderr, "OKAY [%7.3fs]\n", (split - last_start_time)); } } static void InfoMessage(const std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); } static int64_t get_file_size(int fd) { struct stat sb; if (fstat(fd, &sb) == -1) { Loading Loading @@ -606,9 +633,10 @@ static void CheckRequirement(const std::string& cur_product, const std::string& } std::string var_value; if (!fb_getvar(var, &var_value)) { if (fb->GetVar(var, &var_value) != fastboot::SUCCESS) { fprintf(stderr, "FAILED\n\n"); fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb_get_error().c_str()); fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb->Error().c_str()); die("requirements not met!"); } Loading Loading @@ -686,7 +714,7 @@ bool ParseRequirementLine(const std::string& line, std::string* name, std::strin static void HandlePartitionExists(const std::vector<std::string>& options) { const std::string& partition_name = options[0]; std::string has_slot; if (!fb_getvar("has-slot:" + partition_name, &has_slot) || if (fb->GetVar("has-slot:" + partition_name, &has_slot) != fastboot::SUCCESS || (has_slot != "yes" && has_slot != "no")) { die("device doesn't have required partition %s!", partition_name.c_str()); } Loading @@ -705,8 +733,8 @@ static void HandlePartitionExists(const std::vector<std::string>& options) { static void CheckRequirements(const std::string& data) { std::string cur_product; if (!fb_getvar("product", &cur_product)) { fprintf(stderr, "getvar:product FAILED (%s)\n", fb_get_error().c_str()); if (fb->GetVar("product", &cur_product) != fastboot::SUCCESS) { fprintf(stderr, "getvar:product FAILED (%s)\n", fb->Error().c_str()); } auto lines = Split(data, "\n"); Loading @@ -732,12 +760,24 @@ static void CheckRequirements(const std::string& data) { } } static void dump_info() { fb_notice("--------------------------------------------"); fb_display("Bootloader Version...", "version-bootloader"); fb_display("Baseband Version.....", "version-baseband"); fb_display("Serial Number........", "serialno"); fb_notice("--------------------------------------------"); static void DisplayVarOrError(const std::string& label, const std::string& var) { std::string value; if (fb->GetVar(var, &value) != fastboot::SUCCESS) { Status("getvar:" + var); fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); return; } fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str()); } static void DumpInfo() { fprintf(stderr, "--------------------------------------------\n"); DisplayVarOrError("Bootloader Version...", "version-bootloader"); DisplayVarOrError("Baseband Version.....", "version-baseband"); DisplayVarOrError("Serial Number........", "serialno"); fprintf(stderr, "--------------------------------------------\n"); } static struct sparse_file** load_sparse_files(int fd, int64_t max_size) { Loading @@ -762,7 +802,7 @@ static struct sparse_file** load_sparse_files(int fd, int64_t max_size) { static int64_t get_target_sparse_limit() { std::string max_download_size; if (!fb_getvar("max-download-size", &max_download_size) || if (fb->GetVar("max-download-size", &max_download_size) != fastboot::SUCCESS || max_download_size.empty()) { verbose("target didn't report max-download-size"); return 0; Loading Loading @@ -910,12 +950,12 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf) for (size_t i = 0; i < sparse_files.size(); ++i) { const auto& pair = sparse_files[i]; fb_flash_sparse(partition, pair.first, pair.second, i + 1, sparse_files.size()); fb->FlashPartition(partition, pair.first, pair.second, i + 1, sparse_files.size()); } break; } case FB_BUFFER_FD: fb_flash_fd(partition, buf->fd, buf->sz); fb->FlashPartition(partition, buf->fd, buf->sz); break; default: die("unknown buffer type: %d", buf->type); Loading @@ -924,14 +964,15 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf) static std::string get_current_slot() { std::string current_slot; if (!fb_getvar("current-slot", ¤t_slot)) return ""; if (fb->GetVar("current-slot", ¤t_slot) != fastboot::SUCCESS) return ""; return current_slot; } static int get_slot_count() { std::string var; int count = 0; if (!fb_getvar("slot-count", &var) || !android::base::ParseInt(var, &count)) { if (fb->GetVar("slot-count", &var) != fastboot::SUCCESS || !android::base::ParseInt(var, &count)) { return 0; } return count; Loading Loading @@ -1006,7 +1047,7 @@ static void do_for_partition(const std::string& part, const std::string& slot, std::string has_slot; std::string current_slot; if (!fb_getvar("has-slot:" + part, &has_slot)) { if (fb->GetVar("has-slot:" + part, &has_slot) != fastboot::SUCCESS) { /* If has-slot is not supported, the answer is no. */ has_slot = "no"; } Loading Loading @@ -1039,7 +1080,7 @@ static void do_for_partitions(const std::string& part, const std::string& slot, std::string has_slot; if (slot == "all") { if (!fb_getvar("has-slot:" + part, &has_slot)) { if (fb->GetVar("has-slot:" + part, &has_slot) != fastboot::SUCCESS) { die("Could not check if partition %s has slot %s", part.c_str(), slot.c_str()); } if (has_slot == "yes") { Loading Loading @@ -1069,25 +1110,25 @@ static void set_active(const std::string& slot_override) { if (!supports_AB()) return; if (slot_override != "") { fb_set_active(slot_override); fb->SetActive(slot_override); } else { std::string current_slot = get_current_slot(); if (current_slot != "") { fb_set_active(current_slot); fb->SetActive(current_slot); } } } static bool is_userspace_fastboot() { std::string value; return fb_getvar("is-userspace", &value) && value == "yes"; return fb->GetVar("is-userspace", &value) == fastboot::SUCCESS && value == "yes"; } static bool if_partition_exists(const std::string& partition, const std::string& slot) { std::string has_slot; std::string partition_name = partition; if (fb_getvar("has-slot:" + partition, &has_slot) && has_slot == "yes") { if (fb->GetVar("has-slot:" + partition, &has_slot) == fastboot::SUCCESS && has_slot == "yes") { if (slot == "") { std::string current_slot = get_current_slot(); if (current_slot == "") { Loading @@ -1099,23 +1140,24 @@ static bool if_partition_exists(const std::string& partition, const std::string& } } std::string partition_size; return fb_getvar("partition-size:" + partition_name, &partition_size); return fb->GetVar("partition-size:" + partition_name, &partition_size) == fastboot::SUCCESS; } static bool is_logical(const std::string& partition) { std::string value; return fb_getvar("is-logical:" + partition, &value) && value == "yes"; return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes"; } static void reboot_to_userspace_fastboot() { if (!fb_reboot_to_userspace()) { die("Must reboot to userspace fastboot to flash logical partitions"); } fb->RebootTo("fastboot"); auto* old_transport = fb->set_transport(nullptr); delete old_transport; // Give the current connection time to close. std::this_thread::sleep_for(std::chrono::milliseconds(1000)); fb_reinit(open_device()); fb->set_transport(open_device()); } class ImageSource { Loading Loading @@ -1156,6 +1198,7 @@ FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_ov } void FlashAllTool::Flash() { DumpInfo(); CheckRequirements(); DetermineSecondarySlot(); CollectImages(); Loading @@ -1172,7 +1215,7 @@ void FlashAllTool::Flash() { for (const auto& [image, slot] : os_images_) { auto resize_partition = [](const std::string& partition) -> void { if (is_logical(partition)) { fb_resize_partition(partition, "0"); fb->ResizePartition(partition, "0"); } }; do_for_partitions(image->part_name, slot, resize_partition, false); Loading Loading @@ -1248,12 +1291,12 @@ void FlashAllTool::FlashImage(const Image& image, const std::string& slot, fastb auto flash = [&, this](const std::string& partition_name) { std::vector<char> signature_data; if (source_.ReadFile(image.sig_name, &signature_data)) { fb_download("signature", signature_data); fb_command("signature", "installing signature"); fb->Download("signature", signature_data); fb->RawCommand("signature", "installing signature"); } if (is_logical(partition_name)) { fb_resize_partition(partition_name, std::to_string(buf->image_size)); fb->ResizePartition(partition_name, std::to_string(buf->image_size)); } flash_buf(partition_name.c_str(), buf); }; Loading @@ -1272,13 +1315,13 @@ void FlashAllTool::UpdateSuperPartition() { if (!is_userspace_fastboot()) { reboot_to_userspace_fastboot(); } fb_download_fd("super", fd, get_file_size(fd)); fb->Download("super", fd, get_file_size(fd)); std::string command = "update-super:super"; if (wipe_) { command += ":wipe"; } fb_command(command, "Updating super partition"); fb->RawCommand(command, "Updating super partition"); } class ZipImageSource final : public ImageSource { Loading @@ -1300,8 +1343,6 @@ int ZipImageSource::OpenFile(const std::string& name) const { } static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary) { dump_info(); ZipArchiveHandle zip; int error = OpenArchive(filename, &zip); if (error != 0) { Loading Loading @@ -1334,9 +1375,6 @@ int LocalImageSource::OpenFile(const std::string& name) const { } static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) { std::string fname; dump_info(); FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe); tool.Flash(); } Loading @@ -1355,7 +1393,7 @@ static void do_oem_command(const std::string& cmd, std::vector<std::string>* arg while (!args->empty()) { command += " " + next_arg(args); } fb_command(command, ""); fb->RawCommand(command, ""); } static std::string fb_fix_numeric_var(std::string var) { Loading @@ -1369,7 +1407,7 @@ static std::string fb_fix_numeric_var(std::string var) { static unsigned fb_get_flash_block_size(std::string name) { std::string sizeString; if (!fb_getvar(name, &sizeString) || sizeString.empty()) { if (fb->GetVar(name, &sizeString) != fastboot::SUCCESS || sizeString.empty()) { // This device does not report flash block sizes, so return 0. return 0; } Loading Loading @@ -1407,7 +1445,7 @@ static void fb_perform_format( limit = sparse_limit; } if (!fb_getvar("partition-type:" + partition, &partition_type)) { if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) { errMsg = "Can't determine partition type.\n"; goto failed; } Loading @@ -1419,7 +1457,7 @@ static void fb_perform_format( partition_type = type_override; } if (!fb_getvar("partition-size:" + partition, &partition_size)) { if (fb->GetVar("partition-size:" + partition, &partition_size) != fastboot::SUCCESS) { errMsg = "Unable to get partition size\n"; goto failed; } Loading Loading @@ -1477,7 +1515,7 @@ failed: fprintf(stderr, "Erase successful, but not automatically formatting.\n"); if (errMsg) fprintf(stderr, "%s", errMsg); } fprintf(stderr, "FAILED (%s)\n", fb_get_error().c_str()); fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); } int FastBootTool::Main(int argc, char* argv[]) { Loading Loading @@ -1627,8 +1665,13 @@ int FastBootTool::Main(int argc, char* argv[]) { if (transport == nullptr) { return 1; } fastboot::FastBootDriver fb(transport); fb_init(fb); fastboot::DriverCallbacks driver_callbacks = { .prolog = Status, .epilog = Epilog, .info = InfoMessage, }; fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fb = &fastboot_driver; const double start = now(); Loading @@ -1639,7 +1682,7 @@ int FastBootTool::Main(int argc, char* argv[]) { if (next_active == "") { if (slot_override == "") { std::string current_slot; if (fb_getvar("current-slot", ¤t_slot)) { if (fb->GetVar("current-slot", ¤t_slot) == fastboot::SUCCESS) { next_active = verify_slot(current_slot, false); } else { wants_set_active = false; Loading @@ -1656,19 +1699,18 @@ int FastBootTool::Main(int argc, char* argv[]) { if (command == "getvar") { std::string variable = next_arg(&args); fb_display(variable, variable); DisplayVarOrError(variable, variable); } else if (command == "erase") { std::string partition = next_arg(&args); auto erase = [&](const std::string& partition) { std::string partition_type; if (fb_getvar(std::string("partition-type:") + partition, &partition_type) && if (fb->GetVar("partition-type:" + partition, &partition_type) == fastboot::SUCCESS && fs_get_generator(partition_type) != nullptr) { fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n", partition_type.c_str()); } fb_erase(partition); fb->Erase(partition); }; do_for_partitions(partition, slot_override, erase, true); } else if (android::base::StartsWith(command, "format")) { Loading Loading @@ -1698,8 +1740,8 @@ int FastBootTool::Main(int argc, char* argv[]) { die("could not load '%s': %s", filename.c_str(), strerror(errno)); } if (data.size() != 256) die("signature must be 256 bytes (got %zu)", data.size()); fb_download("signature", data); fb_command("signature", "installing signature"); fb->Download("signature", data); fb->RawCommand("signature", "installing signature"); } else if (command == "reboot") { wants_reboot = true; Loading Loading @@ -1727,7 +1769,7 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "reboot-fastboot") { wants_reboot_fastboot = true; } else if (command == "continue") { fb_command("continue", "resuming boot"); fb->Continue(); } else if (command == "boot") { std::string kernel = next_arg(&args); std::string ramdisk; Loading @@ -1736,8 +1778,8 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!args.empty()) second_stage = next_arg(&args); auto data = LoadBootableImage(kernel, ramdisk, second_stage); fb_download("boot.img", data); fb_command("boot", "booting"); fb->Download("boot.img", data); fb->Boot(); } else if (command == "flash") { std::string pname = next_arg(&args); Loading @@ -1763,7 +1805,7 @@ int FastBootTool::Main(int argc, char* argv[]) { auto data = LoadBootableImage(kernel, ramdisk, second_stage); auto flashraw = [&data](const std::string& partition) { fb_flash(partition, data); fb->FlashPartition(partition, data); }; do_for_partitions(partition, slot_override, flashraw, true); } else if (command == "flashall") { Loading @@ -1787,7 +1829,7 @@ int FastBootTool::Main(int argc, char* argv[]) { wants_reboot = true; } else if (command == "set_active") { std::string slot = verify_slot(next_arg(&args), false); fb_set_active(slot); fb->SetActive(slot); } else if (command == "stage") { std::string filename = next_arg(&args); Loading @@ -1795,10 +1837,10 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!load_buf(filename.c_str(), &buf) || buf.type != FB_BUFFER_FD) { die("cannot load '%s'", filename.c_str()); } fb_download_fd(filename, buf.fd, buf.sz); fb->Download(filename, buf.fd, buf.sz); } else if (command == "get_staged") { std::string filename = next_arg(&args); fb_upload(filename); fb->Upload(filename); } else if (command == "oem") { do_oem_command("oem", &args); } else if (command == "flashing") { Loading @@ -1815,14 +1857,14 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "create-logical-partition") { std::string partition = next_arg(&args); std::string size = next_arg(&args); fb_create_partition(partition, size); fb->CreatePartition(partition, size); } else if (command == "delete-logical-partition") { std::string partition = next_arg(&args); fb_delete_partition(partition); fb->DeletePartition(partition); } else if (command == "resize-logical-partition") { std::string partition = next_arg(&args); std::string size = next_arg(&args); fb_resize_partition(partition, size); fb->ResizePartition(partition, size); } else { syntax_error("unknown command %s", command.c_str()); } Loading @@ -1832,9 +1874,11 @@ int FastBootTool::Main(int argc, char* argv[]) { std::vector<std::string> partitions = { "userdata", "cache", "metadata" }; for (const auto& partition : partitions) { std::string partition_type; if (!fb_getvar(std::string{"partition-type:"} + partition, &partition_type)) continue; if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) { continue; } if (partition_type.empty()) continue; fb_erase(partition); fb->Erase(partition); if (partition == "userdata" && set_fbe_marker) { fprintf(stderr, "setting FBE marker on initial userdata...\n"); std::string initial_userdata_dir = create_fbemarker_tmpdir(); Loading @@ -1846,27 +1890,27 @@ int FastBootTool::Main(int argc, char* argv[]) { } } if (wants_set_active) { fb_set_active(next_active); fb->SetActive(next_active); } if (wants_reboot && !skip_reboot) { fb_reboot(); fb_wait_for_disconnect(); fb->Reboot(); fb->WaitForDisconnect(); } else if (wants_reboot_bootloader) { fb_command("reboot-bootloader", "rebooting into bootloader"); fb_wait_for_disconnect(); fb->RebootTo("bootloader"); fb->WaitForDisconnect(); } else if (wants_reboot_recovery) { fb_command("reboot-recovery", "rebooting into recovery"); fb_wait_for_disconnect(); fb->RebootTo("recovery"); fb->WaitForDisconnect(); } else if (wants_reboot_fastboot) { fb_command("reboot-fastboot", "rebooting into fastboot"); fb_wait_for_disconnect(); fb->RebootTo("fastboot"); fb->WaitForDisconnect(); } fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start)); if (Transport* old_transport = fb.set_transport(nullptr)) { auto* old_transport = fb->set_transport(nullptr); delete old_transport; } return 0; } Loading