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