Loading fastboot/Android.mk +1 −1 Original line number Original line Diff line number Diff line Loading @@ -64,6 +64,7 @@ LOCAL_SRC_FILES_windows := usb_windows.cpp LOCAL_C_INCLUDES_windows := development/host/windows/usb/api LOCAL_C_INCLUDES_windows := development/host/windows/usb/api LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CPP_STD := c++17 LOCAL_CXX_STL := $(fastboot_stl) LOCAL_CXX_STL := $(fastboot_stl) LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) Loading @@ -82,7 +83,6 @@ LOCAL_MODULE_HOST_OS := darwin linux windows LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CPP_STD := c++17 LOCAL_CXX_STL := $(fastboot_stl) LOCAL_CXX_STL := $(fastboot_stl) LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) Loading fastboot/fastboot.cpp +82 −12 Original line number Original line Diff line number Diff line Loading @@ -104,9 +104,10 @@ struct fastboot_buffer { void* data; void* data; int64_t sz; int64_t sz; int fd; int fd; int64_t image_size; }; }; static struct { struct Image { const char* nickname; const char* nickname; const char* img_name; const char* img_name; const char* sig_name; const char* sig_name; Loading @@ -114,7 +115,9 @@ static struct { bool optional_if_no_image; bool optional_if_no_image; bool optional_if_no_partition; bool optional_if_no_partition; bool IsSecondary() const { return nickname == nullptr; } bool IsSecondary() const { return nickname == nullptr; } } images[] = { }; static Image images[] = { // clang-format off // clang-format off { "boot", "boot.img", "boot.sig", "boot", false, false }, { "boot", "boot.img", "boot.sig", "boot", false, false }, { nullptr, "boot_other.img", "boot.sig", "boot", true, false }, { nullptr, "boot_other.img", "boot.sig", "boot", true, false }, Loading @@ -128,7 +131,6 @@ static struct { "product_services", "product_services", true, true }, true, true }, { "recovery", "recovery.img", "recovery.sig", "recovery", true, false }, { "recovery", "recovery.img", "recovery.sig", "recovery", true, false }, { "super", "super.img", "super.sig", "super", true, true }, { "system", "system.img", "system.sig", "system", false, true }, { "system", "system.img", "system.sig", "system", false, true }, { nullptr, "system_other.img", "system.sig", "system", true, false }, { nullptr, "system_other.img", "system.sig", "system", true, false }, { "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, false }, { "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, false }, Loading Loading @@ -773,6 +775,13 @@ static bool load_buf_fd(int fd, struct fastboot_buffer* buf) { return false; return false; } } if (sparse_file* s = sparse_file_import_auto(fd, false, false)) { buf->image_size = sparse_file_len(s, false, false); sparse_file_destroy(s); } else { buf->image_size = sz; } lseek64(fd, 0, SEEK_SET); lseek64(fd, 0, SEEK_SET); int64_t limit = get_sparse_limit(sz); int64_t limit = get_sparse_limit(sz); if (limit) { if (limit) { Loading Loading @@ -1044,6 +1053,11 @@ static void set_active(const std::string& slot_override) { } } } } static bool is_userspace_fastboot() { std::string value; return fb_getvar("is-userspace", &value) && value == "yes"; } static bool if_partition_exists(const std::string& partition, const std::string& slot) { static bool if_partition_exists(const std::string& partition, const std::string& slot) { std::string has_slot; std::string has_slot; std::string partition_name = partition; std::string partition_name = partition; Loading Loading @@ -1158,7 +1172,42 @@ static void do_send_signature(const std::string& fn) { fb_queue_command("signature", "installing signature"); fb_queue_command("signature", "installing signature"); } } static void do_flashall(const std::string& slot_override, bool skip_secondary) { static bool is_logical(const std::string& partition) { std::string value; return fb_getvar("is-logical:" + partition, &value) && value == "yes"; } static void update_super_partition(bool force_wipe) { if (!if_partition_exists("super", "")) { return; } std::string image = find_item_given_name("super_empty.img"); if (access(image.c_str(), R_OK) < 0) { return; } if (!is_userspace_fastboot()) { die("Must have userspace fastboot to flash logical partitions"); } int fd = open(image.c_str(), O_RDONLY); if (fd < 0) { die("could not open '%s': %s", image.c_str(), strerror(errno)); } fb_queue_download_fd("super", fd, get_file_size(fd)); std::string command = "update-super:super"; if (force_wipe) { command += ":wipe"; } fb_queue_command(command, "Updating super partition"); // We need these commands to have finished before proceeding, since // otherwise "getvar is-logical" may not return a correct answer below. fb_execute_queue(); } static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) { std::string fname; std::string fname; queue_info_dump(); queue_info_dump(); Loading Loading @@ -1188,6 +1237,10 @@ static void do_flashall(const std::string& slot_override, bool skip_secondary) { } } } } update_super_partition(wipe); // List of partitions to flash and their slots. std::vector<std::pair<const Image*, std::string>> entries; for (size_t i = 0; i < arraysize(images); i++) { for (size_t i = 0; i < arraysize(images); i++) { const char* slot = NULL; const char* slot = NULL; if (images[i].IsSecondary()) { if (images[i].IsSecondary()) { Loading @@ -1196,21 +1249,38 @@ static void do_flashall(const std::string& slot_override, bool skip_secondary) { slot = slot_override.c_str(); slot = slot_override.c_str(); } } if (!slot) continue; if (!slot) continue; fname = find_item_given_name(images[i].img_name); entries.emplace_back(&images[i], slot); // Resize any logical partition to 0, so each partition is reset to 0 // extents, and will achieve more optimal allocation. auto resize_partition = [](const std::string& partition) -> void { if (is_logical(partition)) { fb_queue_resize_partition(partition, "0"); } }; do_for_partitions(images[i].part_name, slot, resize_partition, false); } // Flash each partition in the list if it has a corresponding image. for (const auto& [image, slot] : entries) { fname = find_item_given_name(image->img_name); fastboot_buffer buf; fastboot_buffer buf; if (!load_buf(fname.c_str(), &buf)) { if (!load_buf(fname.c_str(), &buf)) { if (images[i].optional_if_no_image) continue; if (image->optional_if_no_image) continue; die("could not load '%s': %s", images[i].img_name, strerror(errno)); die("could not load '%s': %s", image->img_name, strerror(errno)); } } if (images[i].optional_if_no_partition && if (image->optional_if_no_partition && !if_partition_exists(images[i].part_name, slot)) { !if_partition_exists(image->part_name, slot)) { continue; continue; } } auto flashall = [&](const std::string &partition) { auto flashall = [&](const std::string &partition) { do_send_signature(fname.c_str()); do_send_signature(fname.c_str()); if (is_logical(partition)) { fb_queue_resize_partition(partition, std::to_string(buf.image_size)); } flash_buf(partition.c_str(), &buf); flash_buf(partition.c_str(), &buf); }; }; do_for_partitions(images[i].part_name, slot, flashall, false); do_for_partitions(image->part_name, slot, flashall, false); } } if (slot_override == "all") { if (slot_override == "all") { Loading Loading @@ -1648,9 +1718,9 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "flashall") { } else if (command == "flashall") { if (slot_override == "all") { if (slot_override == "all") { fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); do_flashall(slot_override, true); do_flashall(slot_override, true, wants_wipe); } else { } else { do_flashall(slot_override, skip_secondary); do_flashall(slot_override, skip_secondary, wants_wipe); } } wants_reboot = true; wants_reboot = true; } else if (command == "update") { } else if (command == "update") { Loading fastboot/fs.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -8,7 +8,7 @@ #include <string.h> #include <string.h> #include <sys/stat.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/types.h> #ifndef WIN32 #ifndef _WIN32 #include <sys/wait.h> #include <sys/wait.h> #else #else #include <tchar.h> #include <tchar.h> Loading @@ -27,7 +27,7 @@ using android::base::GetExecutableDirectory; using android::base::StringPrintf; using android::base::StringPrintf; using android::base::unique_fd; using android::base::unique_fd; #ifdef WIN32 #ifdef _WIN32 static int exec_cmd(const char* path, const char** argv, const char** envp) { static int exec_cmd(const char* path, const char** argv, const char** envp) { std::string cmd; std::string cmd; int i = 0; int i = 0; Loading Loading
fastboot/Android.mk +1 −1 Original line number Original line Diff line number Diff line Loading @@ -64,6 +64,7 @@ LOCAL_SRC_FILES_windows := usb_windows.cpp LOCAL_C_INCLUDES_windows := development/host/windows/usb/api LOCAL_C_INCLUDES_windows := development/host/windows/usb/api LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CPP_STD := c++17 LOCAL_CXX_STL := $(fastboot_stl) LOCAL_CXX_STL := $(fastboot_stl) LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) Loading @@ -82,7 +83,6 @@ LOCAL_MODULE_HOST_OS := darwin linux windows LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS := $(fastboot_cflags) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin) LOCAL_CPP_STD := c++17 LOCAL_CXX_STL := $(fastboot_stl) LOCAL_CXX_STL := $(fastboot_stl) LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_HEADER_LIBRARIES := bootimg_headers LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) LOCAL_LDLIBS_darwin := $(fastboot_ldlibs_darwin) Loading
fastboot/fastboot.cpp +82 −12 Original line number Original line Diff line number Diff line Loading @@ -104,9 +104,10 @@ struct fastboot_buffer { void* data; void* data; int64_t sz; int64_t sz; int fd; int fd; int64_t image_size; }; }; static struct { struct Image { const char* nickname; const char* nickname; const char* img_name; const char* img_name; const char* sig_name; const char* sig_name; Loading @@ -114,7 +115,9 @@ static struct { bool optional_if_no_image; bool optional_if_no_image; bool optional_if_no_partition; bool optional_if_no_partition; bool IsSecondary() const { return nickname == nullptr; } bool IsSecondary() const { return nickname == nullptr; } } images[] = { }; static Image images[] = { // clang-format off // clang-format off { "boot", "boot.img", "boot.sig", "boot", false, false }, { "boot", "boot.img", "boot.sig", "boot", false, false }, { nullptr, "boot_other.img", "boot.sig", "boot", true, false }, { nullptr, "boot_other.img", "boot.sig", "boot", true, false }, Loading @@ -128,7 +131,6 @@ static struct { "product_services", "product_services", true, true }, true, true }, { "recovery", "recovery.img", "recovery.sig", "recovery", true, false }, { "recovery", "recovery.img", "recovery.sig", "recovery", true, false }, { "super", "super.img", "super.sig", "super", true, true }, { "system", "system.img", "system.sig", "system", false, true }, { "system", "system.img", "system.sig", "system", false, true }, { nullptr, "system_other.img", "system.sig", "system", true, false }, { nullptr, "system_other.img", "system.sig", "system", true, false }, { "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, false }, { "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, false }, Loading Loading @@ -773,6 +775,13 @@ static bool load_buf_fd(int fd, struct fastboot_buffer* buf) { return false; return false; } } if (sparse_file* s = sparse_file_import_auto(fd, false, false)) { buf->image_size = sparse_file_len(s, false, false); sparse_file_destroy(s); } else { buf->image_size = sz; } lseek64(fd, 0, SEEK_SET); lseek64(fd, 0, SEEK_SET); int64_t limit = get_sparse_limit(sz); int64_t limit = get_sparse_limit(sz); if (limit) { if (limit) { Loading Loading @@ -1044,6 +1053,11 @@ static void set_active(const std::string& slot_override) { } } } } static bool is_userspace_fastboot() { std::string value; return fb_getvar("is-userspace", &value) && value == "yes"; } static bool if_partition_exists(const std::string& partition, const std::string& slot) { static bool if_partition_exists(const std::string& partition, const std::string& slot) { std::string has_slot; std::string has_slot; std::string partition_name = partition; std::string partition_name = partition; Loading Loading @@ -1158,7 +1172,42 @@ static void do_send_signature(const std::string& fn) { fb_queue_command("signature", "installing signature"); fb_queue_command("signature", "installing signature"); } } static void do_flashall(const std::string& slot_override, bool skip_secondary) { static bool is_logical(const std::string& partition) { std::string value; return fb_getvar("is-logical:" + partition, &value) && value == "yes"; } static void update_super_partition(bool force_wipe) { if (!if_partition_exists("super", "")) { return; } std::string image = find_item_given_name("super_empty.img"); if (access(image.c_str(), R_OK) < 0) { return; } if (!is_userspace_fastboot()) { die("Must have userspace fastboot to flash logical partitions"); } int fd = open(image.c_str(), O_RDONLY); if (fd < 0) { die("could not open '%s': %s", image.c_str(), strerror(errno)); } fb_queue_download_fd("super", fd, get_file_size(fd)); std::string command = "update-super:super"; if (force_wipe) { command += ":wipe"; } fb_queue_command(command, "Updating super partition"); // We need these commands to have finished before proceeding, since // otherwise "getvar is-logical" may not return a correct answer below. fb_execute_queue(); } static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) { std::string fname; std::string fname; queue_info_dump(); queue_info_dump(); Loading Loading @@ -1188,6 +1237,10 @@ static void do_flashall(const std::string& slot_override, bool skip_secondary) { } } } } update_super_partition(wipe); // List of partitions to flash and their slots. std::vector<std::pair<const Image*, std::string>> entries; for (size_t i = 0; i < arraysize(images); i++) { for (size_t i = 0; i < arraysize(images); i++) { const char* slot = NULL; const char* slot = NULL; if (images[i].IsSecondary()) { if (images[i].IsSecondary()) { Loading @@ -1196,21 +1249,38 @@ static void do_flashall(const std::string& slot_override, bool skip_secondary) { slot = slot_override.c_str(); slot = slot_override.c_str(); } } if (!slot) continue; if (!slot) continue; fname = find_item_given_name(images[i].img_name); entries.emplace_back(&images[i], slot); // Resize any logical partition to 0, so each partition is reset to 0 // extents, and will achieve more optimal allocation. auto resize_partition = [](const std::string& partition) -> void { if (is_logical(partition)) { fb_queue_resize_partition(partition, "0"); } }; do_for_partitions(images[i].part_name, slot, resize_partition, false); } // Flash each partition in the list if it has a corresponding image. for (const auto& [image, slot] : entries) { fname = find_item_given_name(image->img_name); fastboot_buffer buf; fastboot_buffer buf; if (!load_buf(fname.c_str(), &buf)) { if (!load_buf(fname.c_str(), &buf)) { if (images[i].optional_if_no_image) continue; if (image->optional_if_no_image) continue; die("could not load '%s': %s", images[i].img_name, strerror(errno)); die("could not load '%s': %s", image->img_name, strerror(errno)); } } if (images[i].optional_if_no_partition && if (image->optional_if_no_partition && !if_partition_exists(images[i].part_name, slot)) { !if_partition_exists(image->part_name, slot)) { continue; continue; } } auto flashall = [&](const std::string &partition) { auto flashall = [&](const std::string &partition) { do_send_signature(fname.c_str()); do_send_signature(fname.c_str()); if (is_logical(partition)) { fb_queue_resize_partition(partition, std::to_string(buf.image_size)); } flash_buf(partition.c_str(), &buf); flash_buf(partition.c_str(), &buf); }; }; do_for_partitions(images[i].part_name, slot, flashall, false); do_for_partitions(image->part_name, slot, flashall, false); } } if (slot_override == "all") { if (slot_override == "all") { Loading Loading @@ -1648,9 +1718,9 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "flashall") { } else if (command == "flashall") { if (slot_override == "all") { if (slot_override == "all") { fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); do_flashall(slot_override, true); do_flashall(slot_override, true, wants_wipe); } else { } else { do_flashall(slot_override, skip_secondary); do_flashall(slot_override, skip_secondary, wants_wipe); } } wants_reboot = true; wants_reboot = true; } else if (command == "update") { } else if (command == "update") { Loading
fastboot/fs.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -8,7 +8,7 @@ #include <string.h> #include <string.h> #include <sys/stat.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/types.h> #ifndef WIN32 #ifndef _WIN32 #include <sys/wait.h> #include <sys/wait.h> #else #else #include <tchar.h> #include <tchar.h> Loading @@ -27,7 +27,7 @@ using android::base::GetExecutableDirectory; using android::base::StringPrintf; using android::base::StringPrintf; using android::base::unique_fd; using android::base::unique_fd; #ifdef WIN32 #ifdef _WIN32 static int exec_cmd(const char* path, const char** argv, const char** envp) { static int exec_cmd(const char* path, const char** argv, const char** envp) { std::string cmd; std::string cmd; int i = 0; int i = 0; Loading