| Tom Cherry | 9027af0 | 2018-09-24 15:48:09 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2018 The Android Open Source Project | 
 | 3 |  * All rights reserved. | 
 | 4 |  * | 
 | 5 |  * Redistribution and use in source and binary forms, with or without | 
 | 6 |  * modification, are permitted provided that the following conditions | 
 | 7 |  * are met: | 
 | 8 |  *  * Redistributions of source code must retain the above copyright | 
 | 9 |  *    notice, this list of conditions and the following disclaimer. | 
 | 10 |  *  * Redistributions in binary form must reproduce the above copyright | 
 | 11 |  *    notice, this list of conditions and the following disclaimer in | 
 | 12 |  *    the documentation and/or other materials provided with the | 
 | 13 |  *    distribution. | 
 | 14 |  * | 
 | 15 |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 | 16 |  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 | 17 |  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 
 | 18 |  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 
 | 19 |  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 
 | 20 |  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | 
 | 21 |  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | 
 | 22 |  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | 
 | 23 |  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
 | 24 |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | 
 | 25 |  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
 | 26 |  * SUCH DAMAGE. | 
 | 27 |  */ | 
| Daniel Zheng | 1a01a1c | 2023-01-30 23:29:50 +0000 | [diff] [blame] | 28 | #pragma once | 
| Tom Cherry | 9027af0 | 2018-09-24 15:48:09 -0700 | [diff] [blame] | 29 |  | 
| Daniel Zheng | 750fe6a | 2023-07-28 10:58:56 -0700 | [diff] [blame] | 30 | #include <functional> | 
| Daniel Zheng | 0d30718 | 2023-01-31 21:07:53 +0000 | [diff] [blame] | 31 | #include <string> | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 32 | #include "fastboot_driver.h" | 
| Daniel Zheng | c9e869b | 2023-03-30 14:59:48 -0700 | [diff] [blame] | 33 | #include "fastboot_driver_interface.h" | 
| Daniel Zheng | 65eb246 | 2023-03-30 14:54:13 -0700 | [diff] [blame] | 34 | #include "filesystem.h" | 
| Daniel Zheng | 47d70a5 | 2023-02-14 17:44:40 +0000 | [diff] [blame] | 35 | #include "super_flash_helper.h" | 
| Daniel Zheng | efca333 | 2023-03-30 15:39:14 -0700 | [diff] [blame] | 36 | #include "task.h" | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 37 | #include "util.h" | 
| Daniel Zheng | 0d30718 | 2023-01-31 21:07:53 +0000 | [diff] [blame] | 38 |  | 
| Tom Cherry | 9027af0 | 2018-09-24 15:48:09 -0700 | [diff] [blame] | 39 | #include <bootimg.h> | 
 | 40 |  | 
| Dmitrii Merkurev | cdbfa7a | 2023-03-01 23:50:05 +0000 | [diff] [blame] | 41 | #include "result.h" | 
 | 42 | #include "socket.h" | 
 | 43 | #include "util.h" | 
| Daniel Zheng | 7f8fff0 | 2023-06-21 14:23:56 -0700 | [diff] [blame] | 44 | #include "ziparchive/zip_archive.h" | 
| Dmitrii Merkurev | cdbfa7a | 2023-03-01 23:50:05 +0000 | [diff] [blame] | 45 |  | 
| Tom Cherry | 9027af0 | 2018-09-24 15:48:09 -0700 | [diff] [blame] | 46 | class FastBootTool { | 
 | 47 |   public: | 
 | 48 |     int Main(int argc, char* argv[]); | 
 | 49 |  | 
 | 50 |     void ParseOsPatchLevel(boot_img_hdr_v1*, const char*); | 
 | 51 |     void ParseOsVersion(boot_img_hdr_v1*, const char*); | 
| Jaegeuk Kim | 638d05e | 2020-11-09 08:54:13 -0800 | [diff] [blame] | 52 |     unsigned ParseFsOption(const char*); | 
| Tom Cherry | 9027af0 | 2018-09-24 15:48:09 -0700 | [diff] [blame] | 53 | }; | 
| Daniel Zheng | 0d30718 | 2023-01-31 21:07:53 +0000 | [diff] [blame] | 54 |  | 
| Daniel Zheng | 65eb246 | 2023-03-30 14:54:13 -0700 | [diff] [blame] | 55 | enum fb_buffer_type { | 
 | 56 |     FB_BUFFER_FD, | 
 | 57 |     FB_BUFFER_SPARSE, | 
 | 58 | }; | 
 | 59 |  | 
 | 60 | struct fastboot_buffer { | 
 | 61 |     enum fb_buffer_type type; | 
 | 62 |     std::vector<SparsePtr> files; | 
 | 63 |     int64_t sz; | 
 | 64 |     unique_fd fd; | 
 | 65 |     int64_t image_size; | 
 | 66 | }; | 
 | 67 |  | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 68 | enum class ImageType { | 
 | 69 |     // Must be flashed for device to boot into the kernel. | 
 | 70 |     BootCritical, | 
 | 71 |     // Normal partition to be flashed during "flashall". | 
 | 72 |     Normal, | 
 | 73 |     // Partition that is never flashed during "flashall". | 
 | 74 |     Extra | 
 | 75 | }; | 
 | 76 |  | 
 | 77 | struct Image { | 
 | 78 |     std::string nickname; | 
 | 79 |     std::string img_name; | 
 | 80 |     std::string sig_name; | 
 | 81 |     std::string part_name; | 
 | 82 |     bool optional_if_no_image; | 
 | 83 |     ImageType type; | 
 | 84 |     bool IsSecondary() const { return nickname.empty(); } | 
 | 85 | }; | 
 | 86 |  | 
 | 87 | using ImageEntry = std::pair<const Image*, std::string>; | 
 | 88 |  | 
 | 89 | struct FlashingPlan { | 
| Daniel Zheng | 15e7783 | 2023-03-13 17:09:43 +0000 | [diff] [blame] | 90 |     unsigned fs_options = 0; | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 91 |     // If the image uses the default slot, or the user specified "all", then | 
 | 92 |     // the paired string will be empty. If the image requests a specific slot | 
 | 93 |     // (for example, system_other) it is specified instead. | 
 | 94 |     ImageSource* source; | 
 | 95 |     bool wants_wipe = false; | 
 | 96 |     bool skip_reboot = false; | 
 | 97 |     bool wants_set_active = false; | 
 | 98 |     bool skip_secondary = false; | 
 | 99 |     bool force_flash = false; | 
| Daniel Zheng | d62002c | 2023-06-21 14:27:35 -0700 | [diff] [blame] | 100 |     bool should_optimize_flash_super = true; | 
| Daniel Zheng | 6acfe9b | 2023-07-05 10:23:37 -0700 | [diff] [blame] | 101 |     bool should_use_fastboot_info = true; | 
| Daniel Zheng | cbda2c0 | 2023-07-18 15:04:43 -0700 | [diff] [blame] | 102 |     bool exclude_dynamic_partitions = false; | 
| Daniel Zheng | 5769b26 | 2023-06-21 14:41:11 -0700 | [diff] [blame] | 103 |     uint64_t sparse_limit = 0; | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 104 |  | 
| Daniel Zheng | 1e6456b | 2023-04-10 09:35:48 -0700 | [diff] [blame] | 105 |     std::string slot_override; | 
| Kelvin Zhang | 2a4a45f | 2023-04-03 20:44:05 +0000 | [diff] [blame] | 106 |     std::string current_slot; | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 107 |     std::string secondary_slot; | 
| Daniel Zheng | 29a211c | 2023-03-10 07:23:49 +0000 | [diff] [blame] | 108 |  | 
| Daniel Zheng | bf09c61 | 2023-04-11 09:33:47 -0700 | [diff] [blame] | 109 |     fastboot::IFastBootDriver* fb; | 
| Daniel Zheng | 7df2ab9 | 2023-02-21 18:22:08 +0000 | [diff] [blame] | 110 | }; | 
 | 111 |  | 
| Daniel Zheng | 65eb246 | 2023-03-30 14:54:13 -0700 | [diff] [blame] | 112 | class FlashAllTool { | 
 | 113 |   public: | 
 | 114 |     FlashAllTool(FlashingPlan* fp); | 
 | 115 |  | 
 | 116 |     void Flash(); | 
| Daniel Zheng | c97eeed | 2023-06-21 14:49:52 -0700 | [diff] [blame] | 117 |     std::vector<std::unique_ptr<Task>> CollectTasks(); | 
| Daniel Zheng | 65eb246 | 2023-03-30 14:54:13 -0700 | [diff] [blame] | 118 |  | 
 | 119 |   private: | 
 | 120 |     void CheckRequirements(); | 
 | 121 |     void DetermineSlot(); | 
 | 122 |     void CollectImages(); | 
| Daniel Zheng | ba07ef5 | 2023-06-21 14:14:19 -0700 | [diff] [blame] | 123 |     void AddFlashTasks(const std::vector<std::pair<const Image*, std::string>>& images, | 
 | 124 |                        std::vector<std::unique_ptr<Task>>& tasks); | 
| Daniel Zheng | c97eeed | 2023-06-21 14:49:52 -0700 | [diff] [blame] | 125 |  | 
 | 126 |     std::vector<std::unique_ptr<Task>> CollectTasksFromFastbootInfo(); | 
| Daniel Zheng | ba07ef5 | 2023-06-21 14:14:19 -0700 | [diff] [blame] | 127 |     std::vector<std::unique_ptr<Task>> CollectTasksFromImageList(); | 
| Daniel Zheng | 65eb246 | 2023-03-30 14:54:13 -0700 | [diff] [blame] | 128 |  | 
 | 129 |     std::vector<ImageEntry> boot_images_; | 
 | 130 |     std::vector<ImageEntry> os_images_; | 
| Daniel Zheng | ba07ef5 | 2023-06-21 14:14:19 -0700 | [diff] [blame] | 131 |     std::vector<std::unique_ptr<Task>> tasks_; | 
 | 132 |  | 
| Daniel Zheng | 65eb246 | 2023-03-30 14:54:13 -0700 | [diff] [blame] | 133 |     FlashingPlan* fp_; | 
 | 134 | }; | 
 | 135 |  | 
| Daniel Zheng | 7f8fff0 | 2023-06-21 14:23:56 -0700 | [diff] [blame] | 136 | class ZipImageSource final : public ImageSource { | 
 | 137 |   public: | 
 | 138 |     explicit ZipImageSource(ZipArchiveHandle zip) : zip_(zip) {} | 
 | 139 |     bool ReadFile(const std::string& name, std::vector<char>* out) const override; | 
 | 140 |     unique_fd OpenFile(const std::string& name) const override; | 
 | 141 |  | 
 | 142 |   private: | 
 | 143 |     ZipArchiveHandle zip_; | 
 | 144 | }; | 
 | 145 |  | 
 | 146 | class LocalImageSource final : public ImageSource { | 
 | 147 |   public: | 
 | 148 |     bool ReadFile(const std::string& name, std::vector<char>* out) const override; | 
 | 149 |     unique_fd OpenFile(const std::string& name) const override; | 
 | 150 | }; | 
 | 151 |  | 
| Daniel Zheng | c97eeed | 2023-06-21 14:49:52 -0700 | [diff] [blame] | 152 | char* get_android_product_out(); | 
| Daniel Zheng | 0d30718 | 2023-01-31 21:07:53 +0000 | [diff] [blame] | 153 | bool should_flash_in_userspace(const std::string& partition_name); | 
 | 154 | bool is_userspace_fastboot(); | 
| Daniel Zheng | 791a83b | 2023-05-23 10:42:39 -0700 | [diff] [blame] | 155 | void do_flash(const char* pname, const char* fname, const bool apply_vbmeta, | 
 | 156 |               const FlashingPlan* fp); | 
| Daniel Zheng | 0d30718 | 2023-01-31 21:07:53 +0000 | [diff] [blame] | 157 | void do_for_partitions(const std::string& part, const std::string& slot, | 
 | 158 |                        const std::function<void(const std::string&)>& func, bool force_slot); | 
 | 159 | std::string find_item(const std::string& item); | 
 | 160 | void reboot_to_userspace_fastboot(); | 
 | 161 | void syntax_error(const char* fmt, ...); | 
| Daniel Zheng | 29a211c | 2023-03-10 07:23:49 +0000 | [diff] [blame] | 162 | std::string get_current_slot(); | 
| Dmitrii Merkurev | cdbfa7a | 2023-03-01 23:50:05 +0000 | [diff] [blame] | 163 |  | 
| Daniel Zheng | efca333 | 2023-03-30 15:39:14 -0700 | [diff] [blame] | 164 | // Code for Parsing fastboot-info.txt | 
| Daniel Zheng | 630f29e | 2023-04-28 14:06:45 -0700 | [diff] [blame] | 165 | bool CheckFastbootInfoRequirements(const std::vector<std::string>& command, | 
 | 166 |                                    uint32_t host_tool_version); | 
| Daniel Zheng | efca333 | 2023-03-30 15:39:14 -0700 | [diff] [blame] | 167 | std::unique_ptr<FlashTask> ParseFlashCommand(const FlashingPlan* fp, | 
 | 168 |                                              const std::vector<std::string>& parts); | 
 | 169 | std::unique_ptr<RebootTask> ParseRebootCommand(const FlashingPlan* fp, | 
 | 170 |                                                const std::vector<std::string>& parts); | 
 | 171 | std::unique_ptr<WipeTask> ParseWipeCommand(const FlashingPlan* fp, | 
 | 172 |                                            const std::vector<std::string>& parts); | 
 | 173 | std::unique_ptr<Task> ParseFastbootInfoLine(const FlashingPlan* fp, | 
 | 174 |                                             const std::vector<std::string>& command); | 
| Daniel Zheng | 997ce15 | 2023-05-30 09:24:46 -0700 | [diff] [blame] | 175 | bool AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks); | 
| Daniel Zheng | efca333 | 2023-03-30 15:39:14 -0700 | [diff] [blame] | 176 | std::vector<std::unique_ptr<Task>> ParseFastbootInfo(const FlashingPlan* fp, | 
 | 177 |                                                      const std::vector<std::string>& file); | 
 | 178 |  | 
| Dmitrii Merkurev | cdbfa7a | 2023-03-01 23:50:05 +0000 | [diff] [blame] | 179 | struct NetworkSerial { | 
 | 180 |     Socket::Protocol protocol; | 
 | 181 |     std::string address; | 
 | 182 |     int port; | 
 | 183 | }; | 
 | 184 |  | 
| Daniel Zheng | 47d70a5 | 2023-02-14 17:44:40 +0000 | [diff] [blame] | 185 | Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial); | 
 | 186 | bool supports_AB(); | 
| Daniel Zheng | 29a211c | 2023-03-10 07:23:49 +0000 | [diff] [blame] | 187 | std::string GetPartitionName(const ImageEntry& entry, const std::string& current_slot_); | 
| Daniel Zheng | 47d70a5 | 2023-02-14 17:44:40 +0000 | [diff] [blame] | 188 | void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files); | 
| Daniel Zheng | 5769b26 | 2023-06-21 14:41:11 -0700 | [diff] [blame] | 189 | int64_t get_sparse_limit(int64_t size, const FlashingPlan* fp); | 
| Daniel Zheng | 47d70a5 | 2023-02-14 17:44:40 +0000 | [diff] [blame] | 190 | std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size); | 
 | 191 |  | 
| Daniel Zheng | eabfe27 | 2023-06-21 14:51:54 -0700 | [diff] [blame] | 192 | bool is_retrofit_device(fastboot::IFastBootDriver* fb); | 
| Daniel Zheng | 47d70a5 | 2023-02-14 17:44:40 +0000 | [diff] [blame] | 193 | bool is_logical(const std::string& partition); | 
| Daniel Zheng | 15e7783 | 2023-03-13 17:09:43 +0000 | [diff] [blame] | 194 | void fb_perform_format(const std::string& partition, int skip_if_not_supported, | 
 | 195 |                        const std::string& type_override, const std::string& size_override, | 
| Daniel Zheng | 5769b26 | 2023-06-21 14:41:11 -0700 | [diff] [blame] | 196 |                        const unsigned fs_options, const FlashingPlan* fp); |