1 /*
2 * Copyright (C) 2008 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 */
28
29 #define _LARGEFILE64_SOURCE
30
31 #include <ctype.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <getopt.h>
35 #include <inttypes.h>
36 #include <limits.h>
37 #include <stdint.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/stat.h>
42 #include <sys/time.h>
43 #include <sys/types.h>
44 #include <unistd.h>
45
46 #include <functional>
47 #include <utility>
48 #include <vector>
49
50 #include <android-base/parseint.h>
51 #include <android-base/parsenetaddress.h>
52 #include <android-base/stringprintf.h>
53 #include <android-base/strings.h>
54 #include <sparse/sparse.h>
55 #include <ziparchive/zip_archive.h>
56
57 #include "bootimg_utils.h"
58 #include "diagnose_usb.h"
59 #include "fastboot.h"
60 #include "fs.h"
61 #include "tcp.h"
62 #include "transport.h"
63 #include "udp.h"
64 #include "usb.h"
65
66 #ifndef O_BINARY
67 #define O_BINARY 0
68 #endif
69
70 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
71
72 char cur_product[FB_RESPONSE_SZ + 1];
73
74 static const char* serial = nullptr;
75 static const char* product = nullptr;
76 static const char* cmdline = nullptr;
77 static unsigned short vendor_id = 0;
78 static int long_listing = 0;
79 static int64_t sparse_limit = -1;
80 static int64_t target_sparse_limit = -1;
81
82 static unsigned page_size = 2048;
83 static unsigned base_addr = 0x10000000;
84 static unsigned kernel_offset = 0x00008000;
85 static unsigned ramdisk_offset = 0x01000000;
86 static unsigned second_offset = 0x00f00000;
87 static unsigned tags_offset = 0x00000100;
88
89 static const std::string convert_fbe_marker_filename("convert_fbe");
90
91 enum fb_buffer_type {
92 FB_BUFFER,
93 FB_BUFFER_SPARSE,
94 };
95
96 struct fastboot_buffer {
97 enum fb_buffer_type type;
98 void* data;
99 int64_t sz;
100 };
101
102 static struct {
103 char img_name[17];
104 char sig_name[17];
105 char part_name[9];
106 bool is_optional;
107 bool is_secondary;
108 } images[] = {
109 {"boot.img", "boot.sig", "boot", false, false},
110 {"boot_other.img", "boot.sig", "boot", true, true},
111 {"recovery.img", "recovery.sig", "recovery", true, false},
112 {"system.img", "system.sig", "system", false, false},
113 {"system_other.img", "system.sig", "system", true, true},
114 {"vendor.img", "vendor.sig", "vendor", true, false},
115 {"vendor_other.img", "vendor.sig", "vendor", true, true},
116 };
117
find_item_given_name(const char * img_name,const char * product)118 static std::string find_item_given_name(const char* img_name, const char* product) {
119 char path_c_str[PATH_MAX + 128];
120
121 if(product) {
122 get_my_path(path_c_str);
123 std::string path = path_c_str;
124 path.erase(path.find_last_of('/'));
125 return android::base::StringPrintf("%s/../../../target/product/%s/%s",
126 path.c_str(), product, img_name);
127 }
128
129 char *dir = getenv("ANDROID_PRODUCT_OUT");
130 if (dir == nullptr || dir[0] == '\0') {
131 die("neither -p product specified nor ANDROID_PRODUCT_OUT set");
132 }
133
134 return android::base::StringPrintf("%s/%s", dir, img_name);
135 }
136
find_item(const char * item,const char * product)137 std::string find_item(const char* item, const char* product) {
138 const char *fn;
139
140 if(!strcmp(item,"boot")) {
141 fn = "boot.img";
142 } else if(!strcmp(item,"recovery")) {
143 fn = "recovery.img";
144 } else if(!strcmp(item,"system")) {
145 fn = "system.img";
146 } else if(!strcmp(item,"vendor")) {
147 fn = "vendor.img";
148 } else if(!strcmp(item,"userdata")) {
149 fn = "userdata.img";
150 } else if(!strcmp(item,"cache")) {
151 fn = "cache.img";
152 } else if(!strcmp(item,"info")) {
153 fn = "android-info.txt";
154 } else {
155 fprintf(stderr,"unknown partition '%s'\n", item);
156 return "";
157 }
158
159 return find_item_given_name(fn, product);
160 }
161
get_file_size(int fd)162 static int64_t get_file_size(int fd) {
163 struct stat sb;
164 return fstat(fd, &sb) == -1 ? -1 : sb.st_size;
165 }
166
load_fd(int fd,int64_t * sz)167 static void* load_fd(int fd, int64_t* sz) {
168 int errno_tmp;
169 char* data = nullptr;
170
171 *sz = get_file_size(fd);
172 if (*sz < 0) {
173 goto oops;
174 }
175
176 data = (char*) malloc(*sz);
177 if (data == nullptr) goto oops;
178
179 if(read(fd, data, *sz) != *sz) goto oops;
180 close(fd);
181
182 return data;
183
184 oops:
185 errno_tmp = errno;
186 close(fd);
187 if(data != 0) free(data);
188 errno = errno_tmp;
189 return 0;
190 }
191
load_file(const char * fn,int64_t * sz)192 static void* load_file(const char* fn, int64_t* sz) {
193 int fd = open(fn, O_RDONLY | O_BINARY);
194 if (fd == -1) return nullptr;
195 return load_fd(fd, sz);
196 }
197
match_fastboot_with_serial(usb_ifc_info * info,const char * local_serial)198 static int match_fastboot_with_serial(usb_ifc_info* info, const char* local_serial) {
199 // Require a matching vendor id if the user specified one with -i.
200 if (vendor_id != 0 && info->dev_vendor != vendor_id) {
201 return -1;
202 }
203
204 if (info->ifc_class != 0xff || info->ifc_subclass != 0x42 || info->ifc_protocol != 0x03) {
205 return -1;
206 }
207
208 // require matching serial number or device path if requested
209 // at the command line with the -s option.
210 if (local_serial && (strcmp(local_serial, info->serial_number) != 0 &&
211 strcmp(local_serial, info->device_path) != 0)) return -1;
212 return 0;
213 }
214
match_fastboot(usb_ifc_info * info)215 static int match_fastboot(usb_ifc_info* info) {
216 return match_fastboot_with_serial(info, serial);
217 }
218
list_devices_callback(usb_ifc_info * info)219 static int list_devices_callback(usb_ifc_info* info) {
220 if (match_fastboot_with_serial(info, nullptr) == 0) {
221 std::string serial = info->serial_number;
222 if (!info->writable) {
223 serial = UsbNoPermissionsShortHelpText();
224 }
225 if (!serial[0]) {
226 serial = "????????????";
227 }
228 // output compatible with "adb devices"
229 if (!long_listing) {
230 printf("%s\tfastboot", serial.c_str());
231 } else {
232 printf("%-22s fastboot", serial.c_str());
233 if (strlen(info->device_path) > 0) printf(" %s", info->device_path);
234 }
235 putchar('\n');
236 }
237
238 return -1;
239 }
240
241 // Opens a new Transport connected to a device. If |serial| is non-null it will be used to identify
242 // a specific device, otherwise the first USB device found will be used.
243 //
244 // If |serial| is non-null but invalid, this prints an error message to stderr and returns nullptr.
245 // Otherwise it blocks until the target is available.
246 //
247 // The returned Transport is a singleton, so multiple calls to this function will return the same
248 // object, and the caller should not attempt to delete the returned Transport.
open_device()249 static Transport* open_device() {
250 static Transport* transport = nullptr;
251 bool announce = true;
252
253 if (transport != nullptr) {
254 return transport;
255 }
256
257 Socket::Protocol protocol = Socket::Protocol::kTcp;
258 std::string host;
259 int port = 0;
260 if (serial != nullptr) {
261 const char* net_address = nullptr;
262
263 if (android::base::StartsWith(serial, "tcp:")) {
264 protocol = Socket::Protocol::kTcp;
265 port = tcp::kDefaultPort;
266 net_address = serial + strlen("tcp:");
267 } else if (android::base::StartsWith(serial, "udp:")) {
268 protocol = Socket::Protocol::kUdp;
269 port = udp::kDefaultPort;
270 net_address = serial + strlen("udp:");
271 }
272
273 if (net_address != nullptr) {
274 std::string error;
275 if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) {
276 fprintf(stderr, "error: Invalid network address '%s': %s\n", net_address,
277 error.c_str());
278 return nullptr;
279 }
280 }
281 }
282
283 while (true) {
284 if (!host.empty()) {
285 std::string error;
286 if (protocol == Socket::Protocol::kTcp) {
287 transport = tcp::Connect(host, port, &error).release();
288 } else if (protocol == Socket::Protocol::kUdp) {
289 transport = udp::Connect(host, port, &error).release();
290 }
291
292 if (transport == nullptr && announce) {
293 fprintf(stderr, "error: %s\n", error.c_str());
294 }
295 } else {
296 transport = usb_open(match_fastboot);
297 }
298
299 if (transport != nullptr) {
300 return transport;
301 }
302
303 if (announce) {
304 announce = false;
305 fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device");
306 }
307 usleep(1000);
308 }
309 }
310
list_devices()311 static void list_devices() {
312 // We don't actually open a USB device here,
313 // just getting our callback called so we can
314 // list all the connected devices.
315 usb_open(list_devices_callback);
316 }
317
usage()318 static void usage() {
319 fprintf(stderr,
320 /* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */
321 "usage: fastboot [ <option> ] <command>\n"
322 "\n"
323 "commands:\n"
324 " update <filename> Reflash device from update.zip.\n"
325 " Sets the flashed slot as active.\n"
326 " flashall Flash boot, system, vendor, and --\n"
327 " if found -- recovery. If the device\n"
328 " supports slots, the slot that has\n"
329 " been flashed to is set as active.\n"
330 " Secondary images may be flashed to\n"
331 " an inactive slot.\n"
332 " flash <partition> [ <filename> ] Write a file to a flash partition.\n"
333 " flashing lock Locks the device. Prevents flashing.\n"
334 " flashing unlock Unlocks the device. Allows flashing\n"
335 " any partition except\n"
336 " bootloader-related partitions.\n"
337 " flashing lock_critical Prevents flashing bootloader-related\n"
338 " partitions.\n"
339 " flashing unlock_critical Enables flashing bootloader-related\n"
340 " partitions.\n"
341 " flashing get_unlock_ability Queries bootloader to see if the\n"
342 " device is unlocked.\n"
343 " flashing get_unlock_bootloader_nonce Queries the bootloader to get the\n"
344 " unlock nonce.\n"
345 " flashing unlock_bootloader <request> Issue unlock bootloader using request.\n"
346 " flashing lock_bootloader Locks the bootloader to prevent\n"
347 " bootloader version rollback.\n"
348 " erase <partition> Erase a flash partition.\n"
349 " format[:[<fs type>][:[<size>]] <partition>\n"
350 " Format a flash partition. Can\n"
351 " override the fs type and/or size\n"
352 " the bootloader reports.\n"
353 " getvar <variable> Display a bootloader variable.\n"
354 " set_active <slot> Sets the active slot. If slots are\n"
355 " not supported, this does nothing.\n"
356 " boot <kernel> [ <ramdisk> [ <second> ] ] Download and boot kernel.\n"
357 " flash:raw boot <kernel> [ <ramdisk> [ <second> ] ]\n"
358 " Create bootimage and flash it.\n"
359 " devices [-l] List all connected devices [with\n"
360 " device paths].\n"
361 " continue Continue with autoboot.\n"
362 " reboot [bootloader] Reboot device [into bootloader].\n"
363 " reboot-bootloader Reboot device into bootloader.\n"
364 " help Show this help message.\n"
365 "\n"
366 "options:\n"
367 " -w Erase userdata and cache (and format\n"
368 " if supported by partition type).\n"
369 " -u Do not erase partition before\n"
370 " formatting.\n"
371 " -s <specific device> Specify a device. For USB, provide either\n"
372 " a serial number or path to device port.\n"
373 " For ethernet, provide an address in the\n"
374 " form <protocol>:<hostname>[:port] where\n"
375 " <protocol> is either tcp or udp.\n"
376 " -p <product> Specify product name.\n"
377 " -c <cmdline> Override kernel commandline.\n"
378 " -i <vendor id> Specify a custom USB vendor id.\n"
379 " -b, --base <base_addr> Specify a custom kernel base\n"
380 " address (default: 0x10000000).\n"
381 " --kernel-offset Specify a custom kernel offset.\n"
382 " (default: 0x00008000)\n"
383 " --ramdisk-offset Specify a custom ramdisk offset.\n"
384 " (default: 0x01000000)\n"
385 " --tags-offset Specify a custom tags offset.\n"
386 " (default: 0x00000100)\n"
387 " -n, --page-size <page size> Specify the nand page size\n"
388 " (default: 2048).\n"
389 " -S <size>[K|M|G] Automatically sparse files greater\n"
390 " than 'size'. 0 to disable.\n"
391 " --slot <slot> Specify slot name to be used if the\n"
392 " device supports slots. All operations\n"
393 " on partitions that support slots will\n"
394 " be done on the slot specified.\n"
395 " 'all' can be given to refer to all slots.\n"
396 " 'other' can be given to refer to a\n"
397 " non-current slot. If this flag is not\n"
398 " used, slotted partitions will default\n"
399 " to the current active slot.\n"
400 " -a, --set-active[=<slot>] Sets the active slot. If no slot is\n"
401 " provided, this will default to the value\n"
402 " given by --slot. If slots are not\n"
403 " supported, this sets the current slot\n"
404 " to be active. This will run after all\n"
405 " non-reboot commands.\n"
406 " --skip-secondary Will not flash secondary slots when\n"
407 " performing a flashall or update. This\n"
408 " will preserve data on other slots.\n"
409 #if !defined(_WIN32)
410 " --wipe-and-use-fbe On devices which support it,\n"
411 " erase userdata and cache, and\n"
412 " enable file-based encryption\n"
413 #endif
414 " --unbuffered Do not buffer input or output.\n"
415 " --version Display version.\n"
416 " -h, --help show this message.\n"
417 );
418 }
419
load_bootable_image(const char * kernel,const char * ramdisk,const char * secondstage,int64_t * sz,const char * cmdline)420 static void* load_bootable_image(const char* kernel, const char* ramdisk,
421 const char* secondstage, int64_t* sz,
422 const char* cmdline) {
423 if (kernel == nullptr) {
424 fprintf(stderr, "no image specified\n");
425 return 0;
426 }
427
428 int64_t ksize;
429 void* kdata = load_file(kernel, &ksize);
430 if (kdata == nullptr) {
431 fprintf(stderr, "cannot load '%s': %s\n", kernel, strerror(errno));
432 return 0;
433 }
434
435 // Is this actually a boot image?
436 if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
437 if (cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline);
438
439 if (ramdisk) {
440 fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n");
441 return 0;
442 }
443
444 *sz = ksize;
445 return kdata;
446 }
447
448 void* rdata = nullptr;
449 int64_t rsize = 0;
450 if (ramdisk) {
451 rdata = load_file(ramdisk, &rsize);
452 if (rdata == nullptr) {
453 fprintf(stderr,"cannot load '%s': %s\n", ramdisk, strerror(errno));
454 return 0;
455 }
456 }
457
458 void* sdata = nullptr;
459 int64_t ssize = 0;
460 if (secondstage) {
461 sdata = load_file(secondstage, &ssize);
462 if (sdata == nullptr) {
463 fprintf(stderr,"cannot load '%s': %s\n", secondstage, strerror(errno));
464 return 0;
465 }
466 }
467
468 fprintf(stderr,"creating boot image...\n");
469 int64_t bsize = 0;
470 void* bdata = mkbootimg(kdata, ksize, kernel_offset,
471 rdata, rsize, ramdisk_offset,
472 sdata, ssize, second_offset,
473 page_size, base_addr, tags_offset, &bsize);
474 if (bdata == nullptr) {
475 fprintf(stderr,"failed to create boot.img\n");
476 return 0;
477 }
478 if (cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline);
479 fprintf(stderr, "creating boot image - %" PRId64 " bytes\n", bsize);
480 *sz = bsize;
481
482 return bdata;
483 }
484
unzip_file(ZipArchiveHandle zip,const char * entry_name,int64_t * sz)485 static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* sz)
486 {
487 ZipString zip_entry_name(entry_name);
488 ZipEntry zip_entry;
489 if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
490 fprintf(stderr, "archive does not contain '%s'\n", entry_name);
491 return 0;
492 }
493
494 *sz = zip_entry.uncompressed_length;
495
496 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length));
497 if (data == nullptr) {
498 fprintf(stderr, "failed to allocate %" PRId64 " bytes for '%s'\n", *sz, entry_name);
499 return 0;
500 }
501
502 int error = ExtractToMemory(zip, &zip_entry, data, zip_entry.uncompressed_length);
503 if (error != 0) {
504 fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
505 free(data);
506 return 0;
507 }
508
509 return data;
510 }
511
512 #if defined(_WIN32)
513
514 // TODO: move this to somewhere it can be shared.
515
516 #include <windows.h>
517
518 // Windows' tmpfile(3) requires administrator rights because
519 // it creates temporary files in the root directory.
win32_tmpfile()520 static FILE* win32_tmpfile() {
521 char temp_path[PATH_MAX];
522 DWORD nchars = GetTempPath(sizeof(temp_path), temp_path);
523 if (nchars == 0 || nchars >= sizeof(temp_path)) {
524 fprintf(stderr, "GetTempPath failed, error %ld\n", GetLastError());
525 return nullptr;
526 }
527
528 char filename[PATH_MAX];
529 if (GetTempFileName(temp_path, "fastboot", 0, filename) == 0) {
530 fprintf(stderr, "GetTempFileName failed, error %ld\n", GetLastError());
531 return nullptr;
532 }
533
534 return fopen(filename, "w+bTD");
535 }
536
537 #define tmpfile win32_tmpfile
538
make_temporary_directory()539 static std::string make_temporary_directory() {
540 fprintf(stderr, "make_temporary_directory not supported under Windows, sorry!");
541 return "";
542 }
543
544 #else
545
make_temporary_directory()546 static std::string make_temporary_directory() {
547 const char *tmpdir = getenv("TMPDIR");
548 if (tmpdir == nullptr) {
549 tmpdir = P_tmpdir;
550 }
551 std::string result = std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
552 if (mkdtemp(&result[0]) == NULL) {
553 fprintf(stderr, "Unable to create temporary directory: %s\n",
554 strerror(errno));
555 return "";
556 }
557 return result;
558 }
559
560 #endif
561
create_fbemarker_tmpdir()562 static std::string create_fbemarker_tmpdir() {
563 std::string dir = make_temporary_directory();
564 if (dir.empty()) {
565 fprintf(stderr, "Unable to create local temp directory for FBE marker\n");
566 return "";
567 }
568 std::string marker_file = dir + "/" + convert_fbe_marker_filename;
569 int fd = open(marker_file.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0666);
570 if (fd == -1) {
571 fprintf(stderr, "Unable to create FBE marker file %s locally: %d, %s\n",
572 marker_file.c_str(), errno, strerror(errno));
573 return "";
574 }
575 close(fd);
576 return dir;
577 }
578
delete_fbemarker_tmpdir(const std::string & dir)579 static void delete_fbemarker_tmpdir(const std::string& dir) {
580 std::string marker_file = dir + "/" + convert_fbe_marker_filename;
581 if (unlink(marker_file.c_str()) == -1) {
582 fprintf(stderr, "Unable to delete FBE marker file %s locally: %d, %s\n",
583 marker_file.c_str(), errno, strerror(errno));
584 return;
585 }
586 if (rmdir(dir.c_str()) == -1) {
587 fprintf(stderr, "Unable to delete FBE marker directory %s locally: %d, %s\n",
588 dir.c_str(), errno, strerror(errno));
589 return;
590 }
591 }
592
unzip_to_file(ZipArchiveHandle zip,char * entry_name)593 static int unzip_to_file(ZipArchiveHandle zip, char* entry_name) {
594 FILE* fp = tmpfile();
595 if (fp == nullptr) {
596 fprintf(stderr, "failed to create temporary file for '%s': %s\n",
597 entry_name, strerror(errno));
598 return -1;
599 }
600
601 ZipString zip_entry_name(entry_name);
602 ZipEntry zip_entry;
603 if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
604 fprintf(stderr, "archive does not contain '%s'\n", entry_name);
605 return -1;
606 }
607
608 int fd = fileno(fp);
609 int error = ExtractEntryToFile(zip, &zip_entry, fd);
610 if (error != 0) {
611 fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
612 return -1;
613 }
614
615 lseek(fd, 0, SEEK_SET);
616 return fd;
617 }
618
strip(char * s)619 static char *strip(char *s)
620 {
621 int n;
622 while(*s && isspace(*s)) s++;
623 n = strlen(s);
624 while(n-- > 0) {
625 if(!isspace(s[n])) break;
626 s[n] = 0;
627 }
628 return s;
629 }
630
631 #define MAX_OPTIONS 32
setup_requirement_line(char * name)632 static int setup_requirement_line(char *name)
633 {
634 char *val[MAX_OPTIONS];
635 char *prod = nullptr;
636 unsigned n, count;
637 char *x;
638 int invert = 0;
639
640 if (!strncmp(name, "reject ", 7)) {
641 name += 7;
642 invert = 1;
643 } else if (!strncmp(name, "require ", 8)) {
644 name += 8;
645 invert = 0;
646 } else if (!strncmp(name, "require-for-product:", 20)) {
647 // Get the product and point name past it
648 prod = name + 20;
649 name = strchr(name, ' ');
650 if (!name) return -1;
651 *name = 0;
652 name += 1;
653 invert = 0;
654 }
655
656 x = strchr(name, '=');
657 if (x == 0) return 0;
658 *x = 0;
659 val[0] = x + 1;
660
661 for(count = 1; count < MAX_OPTIONS; count++) {
662 x = strchr(val[count - 1],'|');
663 if (x == 0) break;
664 *x = 0;
665 val[count] = x + 1;
666 }
667
668 name = strip(name);
669 for(n = 0; n < count; n++) val[n] = strip(val[n]);
670
671 name = strip(name);
672 if (name == 0) return -1;
673
674 const char* var = name;
675 // Work around an unfortunate name mismatch.
676 if (!strcmp(name,"board")) var = "product";
677
678 const char** out = reinterpret_cast<const char**>(malloc(sizeof(char*) * count));
679 if (out == 0) return -1;
680
681 for(n = 0; n < count; n++) {
682 out[n] = strdup(strip(val[n]));
683 if (out[n] == 0) {
684 for(size_t i = 0; i < n; ++i) {
685 free((char*) out[i]);
686 }
687 free(out);
688 return -1;
689 }
690 }
691
692 fb_queue_require(prod, var, invert, n, out);
693 return 0;
694 }
695
setup_requirements(char * data,int64_t sz)696 static void setup_requirements(char* data, int64_t sz) {
697 char* s = data;
698 while (sz-- > 0) {
699 if (*s == '\n') {
700 *s++ = 0;
701 if (setup_requirement_line(data)) {
702 die("out of memory");
703 }
704 data = s;
705 } else {
706 s++;
707 }
708 }
709 }
710
queue_info_dump()711 static void queue_info_dump() {
712 fb_queue_notice("--------------------------------------------");
713 fb_queue_display("version-bootloader", "Bootloader Version...");
714 fb_queue_display("version-baseband", "Baseband Version.....");
715 fb_queue_display("serialno", "Serial Number........");
716 fb_queue_notice("--------------------------------------------");
717 }
718
load_sparse_files(int fd,int max_size)719 static struct sparse_file **load_sparse_files(int fd, int max_size)
720 {
721 struct sparse_file* s = sparse_file_import_auto(fd, false, true);
722 if (!s) {
723 die("cannot sparse read file\n");
724 }
725
726 int files = sparse_file_resparse(s, max_size, nullptr, 0);
727 if (files < 0) {
728 die("Failed to resparse\n");
729 }
730
731 sparse_file** out_s = reinterpret_cast<sparse_file**>(calloc(sizeof(struct sparse_file *), files + 1));
732 if (!out_s) {
733 die("Failed to allocate sparse file array\n");
734 }
735
736 files = sparse_file_resparse(s, max_size, out_s, files);
737 if (files < 0) {
738 die("Failed to resparse\n");
739 }
740
741 return out_s;
742 }
743
get_target_sparse_limit(Transport * transport)744 static int64_t get_target_sparse_limit(Transport* transport) {
745 std::string max_download_size;
746 if (!fb_getvar(transport, "max-download-size", &max_download_size) ||
747 max_download_size.empty()) {
748 fprintf(stderr, "target didn't report max-download-size\n");
749 return 0;
750 }
751
752 // Some bootloaders (angler, for example) send spurious whitespace too.
753 max_download_size = android::base::Trim(max_download_size);
754
755 uint64_t limit;
756 if (!android::base::ParseUint(max_download_size.c_str(), &limit)) {
757 fprintf(stderr, "couldn't parse max-download-size '%s'\n", max_download_size.c_str());
758 return 0;
759 }
760 if (limit > 0) {
761 fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit);
762 }
763 return limit;
764 }
765
get_sparse_limit(Transport * transport,int64_t size)766 static int64_t get_sparse_limit(Transport* transport, int64_t size) {
767 int64_t limit;
768
769 if (sparse_limit == 0) {
770 return 0;
771 } else if (sparse_limit > 0) {
772 limit = sparse_limit;
773 } else {
774 if (target_sparse_limit == -1) {
775 target_sparse_limit = get_target_sparse_limit(transport);
776 }
777 if (target_sparse_limit > 0) {
778 limit = target_sparse_limit;
779 } else {
780 return 0;
781 }
782 }
783
784 if (size > limit) {
785 return limit;
786 }
787
788 return 0;
789 }
790
791 // Until we get lazy inode table init working in make_ext4fs, we need to
792 // erase partitions of type ext4 before flashing a filesystem so no stale
793 // inodes are left lying around. Otherwise, e2fsck gets very upset.
needs_erase(Transport * transport,const char * partition)794 static bool needs_erase(Transport* transport, const char* partition) {
795 std::string partition_type;
796 if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
797 return false;
798 }
799 return partition_type == "ext4";
800 }
801
load_buf_fd(Transport * transport,int fd,struct fastboot_buffer * buf)802 static int load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* buf) {
803 int64_t sz = get_file_size(fd);
804 if (sz == -1) {
805 return -1;
806 }
807
808 lseek64(fd, 0, SEEK_SET);
809 int64_t limit = get_sparse_limit(transport, sz);
810 if (limit) {
811 sparse_file** s = load_sparse_files(fd, limit);
812 if (s == nullptr) {
813 return -1;
814 }
815 buf->type = FB_BUFFER_SPARSE;
816 buf->data = s;
817 } else {
818 void* data = load_fd(fd, &sz);
819 if (data == nullptr) return -1;
820 buf->type = FB_BUFFER;
821 buf->data = data;
822 buf->sz = sz;
823 }
824
825 return 0;
826 }
827
load_buf(Transport * transport,const char * fname,struct fastboot_buffer * buf)828 static int load_buf(Transport* transport, const char *fname, struct fastboot_buffer *buf)
829 {
830 int fd;
831
832 fd = open(fname, O_RDONLY | O_BINARY);
833 if (fd < 0) {
834 return -1;
835 }
836
837 return load_buf_fd(transport, fd, buf);
838 }
839
flash_buf(const char * pname,struct fastboot_buffer * buf)840 static void flash_buf(const char *pname, struct fastboot_buffer *buf)
841 {
842 sparse_file** s;
843
844 switch (buf->type) {
845 case FB_BUFFER_SPARSE: {
846 std::vector<std::pair<sparse_file*, int64_t>> sparse_files;
847 s = reinterpret_cast<sparse_file**>(buf->data);
848 while (*s) {
849 int64_t sz = sparse_file_len(*s, true, false);
850 sparse_files.emplace_back(*s, sz);
851 ++s;
852 }
853
854 for (size_t i = 0; i < sparse_files.size(); ++i) {
855 const auto& pair = sparse_files[i];
856 fb_queue_flash_sparse(pname, pair.first, pair.second, i + 1, sparse_files.size());
857 }
858 break;
859 }
860
861 case FB_BUFFER:
862 fb_queue_flash(pname, buf->data, buf->sz);
863 break;
864 default:
865 die("unknown buffer type: %d", buf->type);
866 }
867 }
868
get_current_slot(Transport * transport)869 static std::string get_current_slot(Transport* transport)
870 {
871 std::string current_slot;
872 if (fb_getvar(transport, "current-slot", ¤t_slot)) {
873 if (current_slot == "_a") return "a"; // Legacy support
874 if (current_slot == "_b") return "b"; // Legacy support
875 return current_slot;
876 }
877 return "";
878 }
879
880 // Legacy support
get_suffixes_obsolete(Transport * transport)881 static std::vector<std::string> get_suffixes_obsolete(Transport* transport) {
882 std::vector<std::string> suffixes;
883 std::string suffix_list;
884 if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) {
885 return suffixes;
886 }
887 suffixes = android::base::Split(suffix_list, ",");
888 // Unfortunately some devices will return an error message in the
889 // guise of a valid value. If we only see only one suffix, it's probably
890 // not real.
891 if (suffixes.size() == 1) {
892 suffixes.clear();
893 }
894 return suffixes;
895 }
896
897 // Legacy support
supports_AB_obsolete(Transport * transport)898 static bool supports_AB_obsolete(Transport* transport) {
899 return !get_suffixes_obsolete(transport).empty();
900 }
901
get_slot_count(Transport * transport)902 static int get_slot_count(Transport* transport) {
903 std::string var;
904 int count;
905 if (!fb_getvar(transport, "slot-count", &var)) {
906 if (supports_AB_obsolete(transport)) return 2; // Legacy support
907 }
908 if (!android::base::ParseInt(var.c_str(), &count)) return 0;
909 return count;
910 }
911
supports_AB(Transport * transport)912 static bool supports_AB(Transport* transport) {
913 return get_slot_count(transport) >= 2;
914 }
915
916 // Given a current slot, this returns what the 'other' slot is.
get_other_slot(const std::string & current_slot,int count)917 static std::string get_other_slot(const std::string& current_slot, int count) {
918 if (count == 0) return "";
919
920 char next = (current_slot[0] - 'a' + 1)%count + 'a';
921 return std::string(1, next);
922 }
923
get_other_slot(Transport * transport,const std::string & current_slot)924 static std::string get_other_slot(Transport* transport, const std::string& current_slot) {
925 return get_other_slot(current_slot, get_slot_count(transport));
926 }
927
get_other_slot(Transport * transport,int count)928 static std::string get_other_slot(Transport* transport, int count) {
929 return get_other_slot(get_current_slot(transport), count);
930 }
931
get_other_slot(Transport * transport)932 static std::string get_other_slot(Transport* transport) {
933 return get_other_slot(get_current_slot(transport), get_slot_count(transport));
934 }
935
verify_slot(Transport * transport,const std::string & slot_name,bool allow_all)936 static std::string verify_slot(Transport* transport, const std::string& slot_name, bool allow_all) {
937 std::string slot = slot_name;
938 if (slot == "_a") slot = "a"; // Legacy support
939 if (slot == "_b") slot = "b"; // Legacy support
940 if (slot == "all") {
941 if (allow_all) {
942 return "all";
943 } else {
944 int count = get_slot_count(transport);
945 if (count > 0) {
946 return "a";
947 } else {
948 die("No known slots.");
949 }
950 }
951 }
952
953 int count = get_slot_count(transport);
954 if (count == 0) die("Device does not support slots.\n");
955
956 if (slot == "other") {
957 std::string other = get_other_slot(transport, count);
958 if (other == "") {
959 die("No known slots.");
960 }
961 return other;
962 }
963
964 if (slot.size() == 1 && (slot[0]-'a' >= 0 && slot[0]-'a' < count)) return slot;
965
966 fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot.c_str());
967 for (int i=0; i<count; i++) {
968 fprintf(stderr, "%c\n", (char)(i + 'a'));
969 }
970
971 exit(1);
972 }
973
verify_slot(Transport * transport,const std::string & slot)974 static std::string verify_slot(Transport* transport, const std::string& slot) {
975 return verify_slot(transport, slot, true);
976 }
977
do_for_partition(Transport * transport,const std::string & part,const std::string & slot,std::function<void (const std::string &)> func,bool force_slot)978 static void do_for_partition(Transport* transport, const std::string& part, const std::string& slot,
979 std::function<void(const std::string&)> func, bool force_slot) {
980 std::string has_slot;
981 std::string current_slot;
982
983 if (!fb_getvar(transport, "has-slot:" + part, &has_slot)) {
984 /* If has-slot is not supported, the answer is no. */
985 has_slot = "no";
986 }
987 if (has_slot == "yes") {
988 if (slot == "") {
989 current_slot = get_current_slot(transport);
990 if (current_slot == "") {
991 die("Failed to identify current slot.\n");
992 }
993 func(part + "_" + current_slot);
994 } else {
995 func(part + '_' + slot);
996 }
997 } else {
998 if (force_slot && slot != "") {
999 fprintf(stderr, "Warning: %s does not support slots, and slot %s was requested.\n",
1000 part.c_str(), slot.c_str());
1001 }
1002 func(part);
1003 }
1004 }
1005
1006 /* This function will find the real partition name given a base name, and a slot. If slot is NULL or
1007 * empty, it will use the current slot. If slot is "all", it will return a list of all possible
1008 * partition names. If force_slot is true, it will fail if a slot is specified, and the given
1009 * partition does not support slots.
1010 */
do_for_partitions(Transport * transport,const std::string & part,const std::string & slot,std::function<void (const std::string &)> func,bool force_slot)1011 static void do_for_partitions(Transport* transport, const std::string& part, const std::string& slot,
1012 std::function<void(const std::string&)> func, bool force_slot) {
1013 std::string has_slot;
1014
1015 if (slot == "all") {
1016 if (!fb_getvar(transport, "has-slot:" + part, &has_slot)) {
1017 die("Could not check if partition %s has slot.", part.c_str());
1018 }
1019 if (has_slot == "yes") {
1020 for (int i=0; i < get_slot_count(transport); i++) {
1021 do_for_partition(transport, part, std::string(1, (char)(i + 'a')), func, force_slot);
1022 }
1023 } else {
1024 do_for_partition(transport, part, "", func, force_slot);
1025 }
1026 } else {
1027 do_for_partition(transport, part, slot, func, force_slot);
1028 }
1029 }
1030
do_flash(Transport * transport,const char * pname,const char * fname)1031 static void do_flash(Transport* transport, const char* pname, const char* fname) {
1032 struct fastboot_buffer buf;
1033
1034 if (load_buf(transport, fname, &buf)) {
1035 die("cannot load '%s'", fname);
1036 }
1037 flash_buf(pname, &buf);
1038 }
1039
do_update_signature(ZipArchiveHandle zip,char * fn)1040 static void do_update_signature(ZipArchiveHandle zip, char* fn) {
1041 int64_t sz;
1042 void* data = unzip_file(zip, fn, &sz);
1043 if (data == nullptr) return;
1044 fb_queue_download("signature", data, sz);
1045 fb_queue_command("signature", "installing signature");
1046 }
1047
1048 // Sets slot_override as the active slot. If slot_override is blank,
1049 // set current slot as active instead. This clears slot-unbootable.
set_active(Transport * transport,const std::string & slot_override)1050 static void set_active(Transport* transport, const std::string& slot_override) {
1051 std::string separator = "";
1052 if (!supports_AB(transport)) {
1053 if (supports_AB_obsolete(transport)) {
1054 separator = "_"; // Legacy support
1055 } else {
1056 return;
1057 }
1058 }
1059 if (slot_override != "") {
1060 fb_set_active((separator + slot_override).c_str());
1061 } else {
1062 std::string current_slot = get_current_slot(transport);
1063 if (current_slot != "") {
1064 fb_set_active((separator + current_slot).c_str());
1065 }
1066 }
1067 }
1068
do_update(Transport * transport,const char * filename,const std::string & slot_override,bool erase_first,bool skip_secondary)1069 static void do_update(Transport* transport, const char* filename, const std::string& slot_override, bool erase_first, bool skip_secondary) {
1070 queue_info_dump();
1071
1072 fb_queue_query_save("product", cur_product, sizeof(cur_product));
1073
1074 ZipArchiveHandle zip;
1075 int error = OpenArchive(filename, &zip);
1076 if (error != 0) {
1077 CloseArchive(zip);
1078 die("failed to open zip file '%s': %s", filename, ErrorCodeString(error));
1079 }
1080
1081 int64_t sz;
1082 void* data = unzip_file(zip, "android-info.txt", &sz);
1083 if (data == nullptr) {
1084 CloseArchive(zip);
1085 die("update package '%s' has no android-info.txt", filename);
1086 }
1087
1088 setup_requirements(reinterpret_cast<char*>(data), sz);
1089
1090 std::string secondary;
1091 if (!skip_secondary) {
1092 if (slot_override != "") {
1093 secondary = get_other_slot(transport, slot_override);
1094 } else {
1095 secondary = get_other_slot(transport);
1096 }
1097 if (secondary == "") {
1098 if (supports_AB(transport)) {
1099 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
1100 }
1101 skip_secondary = true;
1102 }
1103 }
1104 for (size_t i = 0; i < ARRAY_SIZE(images); ++i) {
1105 const char* slot = slot_override.c_str();
1106 if (images[i].is_secondary) {
1107 if (!skip_secondary) {
1108 slot = secondary.c_str();
1109 } else {
1110 continue;
1111 }
1112 }
1113
1114 int fd = unzip_to_file(zip, images[i].img_name);
1115 if (fd == -1) {
1116 if (images[i].is_optional) {
1117 continue;
1118 }
1119 CloseArchive(zip);
1120 exit(1); // unzip_to_file already explained why.
1121 }
1122 fastboot_buffer buf;
1123 int rc = load_buf_fd(transport, fd, &buf);
1124 if (rc) die("cannot load %s from flash", images[i].img_name);
1125
1126 auto update = [&](const std::string &partition) {
1127 do_update_signature(zip, images[i].sig_name);
1128 if (erase_first && needs_erase(transport, partition.c_str())) {
1129 fb_queue_erase(partition.c_str());
1130 }
1131 flash_buf(partition.c_str(), &buf);
1132 /* not closing the fd here since the sparse code keeps the fd around
1133 * but hasn't mmaped data yet. The tmpfile will get cleaned up when the
1134 * program exits.
1135 */
1136 };
1137 do_for_partitions(transport, images[i].part_name, slot, update, false);
1138 }
1139
1140 CloseArchive(zip);
1141 if (slot_override == "all") {
1142 set_active(transport, "a");
1143 } else {
1144 set_active(transport, slot_override);
1145 }
1146 }
1147
do_send_signature(const std::string & fn)1148 static void do_send_signature(const std::string& fn) {
1149 std::size_t extension_loc = fn.find(".img");
1150 if (extension_loc == std::string::npos) return;
1151
1152 std::string fs_sig = fn.substr(0, extension_loc) + ".sig";
1153
1154 int64_t sz;
1155 void* data = load_file(fs_sig.c_str(), &sz);
1156 if (data == nullptr) return;
1157 fb_queue_download("signature", data, sz);
1158 fb_queue_command("signature", "installing signature");
1159 }
1160
do_flashall(Transport * transport,const std::string & slot_override,int erase_first,bool skip_secondary)1161 static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool skip_secondary) {
1162 std::string fname;
1163 queue_info_dump();
1164
1165 fb_queue_query_save("product", cur_product, sizeof(cur_product));
1166
1167 fname = find_item("info", product);
1168 if (fname == "") die("cannot find android-info.txt");
1169
1170 int64_t sz;
1171 void* data = load_file(fname.c_str(), &sz);
1172 if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno));
1173
1174 setup_requirements(reinterpret_cast<char*>(data), sz);
1175
1176 std::string secondary;
1177 if (!skip_secondary) {
1178 if (slot_override != "") {
1179 secondary = get_other_slot(transport, slot_override);
1180 } else {
1181 secondary = get_other_slot(transport);
1182 }
1183 if (secondary == "") {
1184 if (supports_AB(transport)) {
1185 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
1186 }
1187 skip_secondary = true;
1188 }
1189 }
1190
1191 for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
1192 const char* slot = NULL;
1193 if (images[i].is_secondary) {
1194 if (!skip_secondary) slot = secondary.c_str();
1195 } else {
1196 slot = slot_override.c_str();
1197 }
1198 if (!slot) continue;
1199 fname = find_item_given_name(images[i].img_name, product);
1200 fastboot_buffer buf;
1201 if (load_buf(transport, fname.c_str(), &buf)) {
1202 if (images[i].is_optional) continue;
1203 die("could not load %s\n", images[i].img_name);
1204 }
1205
1206 auto flashall = [&](const std::string &partition) {
1207 do_send_signature(fname);
1208 if (erase_first && needs_erase(transport, partition.c_str())) {
1209 fb_queue_erase(partition.c_str());
1210 }
1211 flash_buf(partition.c_str(), &buf);
1212 };
1213 do_for_partitions(transport, images[i].part_name, slot, flashall, false);
1214 }
1215
1216 if (slot_override == "all") {
1217 set_active(transport, "a");
1218 } else {
1219 set_active(transport, slot_override);
1220 }
1221 }
1222
1223 #define skip(n) do { argc -= (n); argv += (n); } while (0)
1224 #define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0)
1225
do_bypass_unlock_command(int argc,char ** argv)1226 static int do_bypass_unlock_command(int argc, char **argv)
1227 {
1228 if (argc <= 2) return 0;
1229 skip(2);
1230
1231 /*
1232 * Process unlock_bootloader, we have to load the message file
1233 * and send that to the remote device.
1234 */
1235 require(1);
1236
1237 int64_t sz;
1238 void* data = load_file(*argv, &sz);
1239 if (data == nullptr) die("could not load '%s': %s", *argv, strerror(errno));
1240 fb_queue_download("unlock_message", data, sz);
1241 fb_queue_command("flashing unlock_bootloader", "unlocking bootloader");
1242 skip(1);
1243 return 0;
1244 }
1245
do_oem_command(int argc,char ** argv)1246 static int do_oem_command(int argc, char **argv)
1247 {
1248 char command[256];
1249 if (argc <= 1) return 0;
1250
1251 command[0] = 0;
1252 while(1) {
1253 strcat(command,*argv);
1254 skip(1);
1255 if(argc == 0) break;
1256 strcat(command," ");
1257 }
1258
1259 fb_queue_command(command,"");
1260 return 0;
1261 }
1262
parse_num(const char * arg)1263 static int64_t parse_num(const char *arg)
1264 {
1265 char *endptr;
1266 unsigned long long num;
1267
1268 num = strtoull(arg, &endptr, 0);
1269 if (endptr == arg) {
1270 return -1;
1271 }
1272
1273 if (*endptr == 'k' || *endptr == 'K') {
1274 if (num >= (-1ULL) / 1024) {
1275 return -1;
1276 }
1277 num *= 1024LL;
1278 endptr++;
1279 } else if (*endptr == 'm' || *endptr == 'M') {
1280 if (num >= (-1ULL) / (1024 * 1024)) {
1281 return -1;
1282 }
1283 num *= 1024LL * 1024LL;
1284 endptr++;
1285 } else if (*endptr == 'g' || *endptr == 'G') {
1286 if (num >= (-1ULL) / (1024 * 1024 * 1024)) {
1287 return -1;
1288 }
1289 num *= 1024LL * 1024LL * 1024LL;
1290 endptr++;
1291 }
1292
1293 if (*endptr != '\0') {
1294 return -1;
1295 }
1296
1297 if (num > INT64_MAX) {
1298 return -1;
1299 }
1300
1301 return num;
1302 }
1303
fb_perform_format(Transport * transport,const char * partition,int skip_if_not_supported,const char * type_override,const char * size_override,const std::string & initial_dir)1304 static void fb_perform_format(Transport* transport,
1305 const char* partition, int skip_if_not_supported,
1306 const char* type_override, const char* size_override,
1307 const std::string& initial_dir) {
1308 std::string partition_type, partition_size;
1309
1310 struct fastboot_buffer buf;
1311 const char* errMsg = nullptr;
1312 const struct fs_generator* gen = nullptr;
1313 int fd;
1314
1315 unsigned int limit = INT_MAX;
1316 if (target_sparse_limit > 0 && target_sparse_limit < limit) {
1317 limit = target_sparse_limit;
1318 }
1319 if (sparse_limit > 0 && sparse_limit < limit) {
1320 limit = sparse_limit;
1321 }
1322
1323 if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
1324 errMsg = "Can't determine partition type.\n";
1325 goto failed;
1326 }
1327 if (type_override) {
1328 if (partition_type != type_override) {
1329 fprintf(stderr, "Warning: %s type is %s, but %s was requested for formatting.\n",
1330 partition, partition_type.c_str(), type_override);
1331 }
1332 partition_type = type_override;
1333 }
1334
1335 if (!fb_getvar(transport, std::string("partition-size:") + partition, &partition_size)) {
1336 errMsg = "Unable to get partition size\n";
1337 goto failed;
1338 }
1339 if (size_override) {
1340 if (partition_size != size_override) {
1341 fprintf(stderr, "Warning: %s size is %s, but %s was requested for formatting.\n",
1342 partition, partition_size.c_str(), size_override);
1343 }
1344 partition_size = size_override;
1345 }
1346 // Some bootloaders (angler, for example), send spurious leading whitespace.
1347 partition_size = android::base::Trim(partition_size);
1348 // Some bootloaders (hammerhead, for example) use implicit hex.
1349 // This code used to use strtol with base 16.
1350 if (!android::base::StartsWith(partition_size, "0x")) partition_size = "0x" + partition_size;
1351
1352 gen = fs_get_generator(partition_type);
1353 if (!gen) {
1354 if (skip_if_not_supported) {
1355 fprintf(stderr, "Erase successful, but not automatically formatting.\n");
1356 fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str());
1357 return;
1358 }
1359 fprintf(stderr, "Formatting is not supported for file system with type '%s'.\n",
1360 partition_type.c_str());
1361 return;
1362 }
1363
1364 int64_t size;
1365 if (!android::base::ParseInt(partition_size.c_str(), &size)) {
1366 fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str());
1367 return;
1368 }
1369
1370 fd = fileno(tmpfile());
1371 if (fs_generator_generate(gen, fd, size, initial_dir)) {
1372 fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
1373 close(fd);
1374 return;
1375 }
1376
1377 if (load_buf_fd(transport, fd, &buf)) {
1378 fprintf(stderr, "Cannot read image: %s\n", strerror(errno));
1379 close(fd);
1380 return;
1381 }
1382 flash_buf(partition, &buf);
1383 return;
1384
1385 failed:
1386 if (skip_if_not_supported) {
1387 fprintf(stderr, "Erase successful, but not automatically formatting.\n");
1388 if (errMsg) fprintf(stderr, "%s", errMsg);
1389 }
1390 fprintf(stderr,"FAILED (%s)\n", fb_get_error());
1391 }
1392
main(int argc,char ** argv)1393 int main(int argc, char **argv)
1394 {
1395 bool wants_wipe = false;
1396 bool wants_reboot = false;
1397 bool wants_reboot_bootloader = false;
1398 bool wants_set_active = false;
1399 bool skip_secondary = false;
1400 bool erase_first = true;
1401 bool set_fbe_marker = false;
1402 void *data;
1403 int64_t sz;
1404 int longindex;
1405 std::string slot_override;
1406 std::string next_active;
1407
1408 const struct option longopts[] = {
1409 {"base", required_argument, 0, 'b'},
1410 {"kernel_offset", required_argument, 0, 'k'},
1411 {"kernel-offset", required_argument, 0, 'k'},
1412 {"page_size", required_argument, 0, 'n'},
1413 {"page-size", required_argument, 0, 'n'},
1414 {"ramdisk_offset", required_argument, 0, 'r'},
1415 {"ramdisk-offset", required_argument, 0, 'r'},
1416 {"tags_offset", required_argument, 0, 't'},
1417 {"tags-offset", required_argument, 0, 't'},
1418 {"help", no_argument, 0, 'h'},
1419 {"unbuffered", no_argument, 0, 0},
1420 {"version", no_argument, 0, 0},
1421 {"slot", required_argument, 0, 0},
1422 {"set_active", optional_argument, 0, 'a'},
1423 {"set-active", optional_argument, 0, 'a'},
1424 {"skip-secondary", no_argument, 0, 0},
1425 #if !defined(_WIN32)
1426 {"wipe-and-use-fbe", no_argument, 0, 0},
1427 #endif
1428 {0, 0, 0, 0}
1429 };
1430
1431 serial = getenv("ANDROID_SERIAL");
1432
1433 while (1) {
1434 int c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:ha::", longopts, &longindex);
1435 if (c < 0) {
1436 break;
1437 }
1438 /* Alphabetical cases */
1439 switch (c) {
1440 case 'a':
1441 wants_set_active = true;
1442 if (optarg)
1443 next_active = optarg;
1444 break;
1445 case 'b':
1446 base_addr = strtoul(optarg, 0, 16);
1447 break;
1448 case 'c':
1449 cmdline = optarg;
1450 break;
1451 case 'h':
1452 usage();
1453 return 1;
1454 case 'i': {
1455 char *endptr = nullptr;
1456 unsigned long val;
1457
1458 val = strtoul(optarg, &endptr, 0);
1459 if (!endptr || *endptr != '\0' || (val & ~0xffff))
1460 die("invalid vendor id '%s'", optarg);
1461 vendor_id = (unsigned short)val;
1462 break;
1463 }
1464 case 'k':
1465 kernel_offset = strtoul(optarg, 0, 16);
1466 break;
1467 case 'l':
1468 long_listing = 1;
1469 break;
1470 case 'n':
1471 page_size = (unsigned)strtoul(optarg, nullptr, 0);
1472 if (!page_size) die("invalid page size");
1473 break;
1474 case 'p':
1475 product = optarg;
1476 break;
1477 case 'r':
1478 ramdisk_offset = strtoul(optarg, 0, 16);
1479 break;
1480 case 't':
1481 tags_offset = strtoul(optarg, 0, 16);
1482 break;
1483 case 's':
1484 serial = optarg;
1485 break;
1486 case 'S':
1487 sparse_limit = parse_num(optarg);
1488 if (sparse_limit < 0) {
1489 die("invalid sparse limit");
1490 }
1491 break;
1492 case 'u':
1493 erase_first = false;
1494 break;
1495 case 'w':
1496 wants_wipe = true;
1497 break;
1498 case '?':
1499 return 1;
1500 case 0:
1501 if (strcmp("unbuffered", longopts[longindex].name) == 0) {
1502 setvbuf(stdout, nullptr, _IONBF, 0);
1503 setvbuf(stderr, nullptr, _IONBF, 0);
1504 } else if (strcmp("version", longopts[longindex].name) == 0) {
1505 fprintf(stdout, "fastboot version %s\n", FASTBOOT_REVISION);
1506 return 0;
1507 } else if (strcmp("slot", longopts[longindex].name) == 0) {
1508 slot_override = std::string(optarg);
1509 } else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
1510 skip_secondary = true;
1511 #if !defined(_WIN32)
1512 } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
1513 wants_wipe = true;
1514 set_fbe_marker = true;
1515 #endif
1516 } else {
1517 fprintf(stderr, "Internal error in options processing for %s\n",
1518 longopts[longindex].name);
1519 return 1;
1520 }
1521 break;
1522 default:
1523 abort();
1524 }
1525 }
1526
1527 argc -= optind;
1528 argv += optind;
1529
1530 if (argc == 0 && !wants_wipe && !wants_set_active) {
1531 usage();
1532 return 1;
1533 }
1534
1535 if (argc > 0 && !strcmp(*argv, "devices")) {
1536 skip(1);
1537 list_devices();
1538 return 0;
1539 }
1540
1541 if (argc > 0 && !strcmp(*argv, "help")) {
1542 usage();
1543 return 0;
1544 }
1545
1546 Transport* transport = open_device();
1547 if (transport == nullptr) {
1548 return 1;
1549 }
1550
1551 if (!supports_AB(transport) && supports_AB_obsolete(transport)) {
1552 fprintf(stderr, "Warning: Device A/B support is outdated. Bootloader update required.\n");
1553 }
1554 if (slot_override != "") slot_override = verify_slot(transport, slot_override);
1555 if (next_active != "") next_active = verify_slot(transport, next_active, false);
1556
1557 if (wants_set_active) {
1558 if (next_active == "") {
1559 if (slot_override == "") {
1560 std::string current_slot;
1561 if (fb_getvar(transport, "current-slot", ¤t_slot)) {
1562 next_active = verify_slot(transport, current_slot, false);
1563 } else {
1564 wants_set_active = false;
1565 }
1566 } else {
1567 next_active = verify_slot(transport, slot_override, false);
1568 }
1569 }
1570 }
1571
1572 while (argc > 0) {
1573 if (!strcmp(*argv, "getvar")) {
1574 require(2);
1575 fb_queue_display(argv[1], argv[1]);
1576 skip(2);
1577 } else if(!strcmp(*argv, "erase")) {
1578 require(2);
1579
1580 auto erase = [&](const std::string &partition) {
1581 std::string partition_type;
1582 if (fb_getvar(transport, std::string("partition-type:") + argv[1], &partition_type) &&
1583 fs_get_generator(partition_type) != nullptr) {
1584 fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n",
1585 partition_type.c_str());
1586 }
1587
1588 fb_queue_erase(partition.c_str());
1589 };
1590 do_for_partitions(transport, argv[1], slot_override, erase, true);
1591 skip(2);
1592 } else if(!strncmp(*argv, "format", strlen("format"))) {
1593 char *overrides;
1594 char *type_override = nullptr;
1595 char *size_override = nullptr;
1596 require(2);
1597 /*
1598 * Parsing for: "format[:[type][:[size]]]"
1599 * Some valid things:
1600 * - select ontly the size, and leave default fs type:
1601 * format::0x4000000 userdata
1602 * - default fs type and size:
1603 * format userdata
1604 * format:: userdata
1605 */
1606 overrides = strchr(*argv, ':');
1607 if (overrides) {
1608 overrides++;
1609 size_override = strchr(overrides, ':');
1610 if (size_override) {
1611 size_override[0] = '\0';
1612 size_override++;
1613 }
1614 type_override = overrides;
1615 }
1616 if (type_override && !type_override[0]) type_override = nullptr;
1617 if (size_override && !size_override[0]) size_override = nullptr;
1618
1619 auto format = [&](const std::string &partition) {
1620 if (erase_first && needs_erase(transport, partition.c_str())) {
1621 fb_queue_erase(partition.c_str());
1622 }
1623 fb_perform_format(transport, partition.c_str(), 0,
1624 type_override, size_override, "");
1625 };
1626 do_for_partitions(transport, argv[1], slot_override, format, true);
1627 skip(2);
1628 } else if(!strcmp(*argv, "signature")) {
1629 require(2);
1630 data = load_file(argv[1], &sz);
1631 if (data == nullptr) die("could not load '%s': %s", argv[1], strerror(errno));
1632 if (sz != 256) die("signature must be 256 bytes");
1633 fb_queue_download("signature", data, sz);
1634 fb_queue_command("signature", "installing signature");
1635 skip(2);
1636 } else if(!strcmp(*argv, "reboot")) {
1637 wants_reboot = true;
1638 skip(1);
1639 if (argc > 0) {
1640 if (!strcmp(*argv, "bootloader")) {
1641 wants_reboot = false;
1642 wants_reboot_bootloader = true;
1643 skip(1);
1644 }
1645 }
1646 require(0);
1647 } else if(!strcmp(*argv, "reboot-bootloader")) {
1648 wants_reboot_bootloader = true;
1649 skip(1);
1650 } else if (!strcmp(*argv, "continue")) {
1651 fb_queue_command("continue", "resuming boot");
1652 skip(1);
1653 } else if(!strcmp(*argv, "boot")) {
1654 char *kname = 0;
1655 char *rname = 0;
1656 char *sname = 0;
1657 skip(1);
1658 if (argc > 0) {
1659 kname = argv[0];
1660 skip(1);
1661 }
1662 if (argc > 0) {
1663 rname = argv[0];
1664 skip(1);
1665 }
1666 if (argc > 0) {
1667 sname = argv[0];
1668 skip(1);
1669 }
1670 data = load_bootable_image(kname, rname, sname, &sz, cmdline);
1671 if (data == 0) return 1;
1672 fb_queue_download("boot.img", data, sz);
1673 fb_queue_command("boot", "booting");
1674 } else if(!strcmp(*argv, "flash")) {
1675 char *pname = argv[1];
1676 std::string fname;
1677 require(2);
1678 if (argc > 2) {
1679 fname = argv[2];
1680 skip(3);
1681 } else {
1682 fname = find_item(pname, product);
1683 skip(2);
1684 }
1685 if (fname == "") die("cannot determine image filename for '%s'", pname);
1686
1687 auto flash = [&](const std::string &partition) {
1688 if (erase_first && needs_erase(transport, partition.c_str())) {
1689 fb_queue_erase(partition.c_str());
1690 }
1691 do_flash(transport, partition.c_str(), fname.c_str());
1692 };
1693 do_for_partitions(transport, pname, slot_override, flash, true);
1694 } else if(!strcmp(*argv, "flash:raw")) {
1695 char *kname = argv[2];
1696 char *rname = 0;
1697 char *sname = 0;
1698 require(3);
1699 skip(3);
1700 if (argc > 0) {
1701 rname = argv[0];
1702 skip(1);
1703 }
1704 if (argc > 0) {
1705 sname = argv[0];
1706 skip(1);
1707 }
1708 data = load_bootable_image(kname, rname, sname, &sz, cmdline);
1709 if (data == 0) die("cannot load bootable image");
1710 auto flashraw = [&](const std::string &partition) {
1711 fb_queue_flash(partition.c_str(), data, sz);
1712 };
1713 do_for_partitions(transport, argv[1], slot_override, flashraw, true);
1714 } else if(!strcmp(*argv, "flashall")) {
1715 skip(1);
1716 if (slot_override == "all") {
1717 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
1718 do_flashall(transport, slot_override, erase_first, true);
1719 } else {
1720 do_flashall(transport, slot_override, erase_first, skip_secondary);
1721 }
1722 wants_reboot = true;
1723 } else if(!strcmp(*argv, "update")) {
1724 bool slot_all = (slot_override == "all");
1725 if (slot_all) {
1726 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
1727 }
1728 if (argc > 1) {
1729 do_update(transport, argv[1], slot_override, erase_first, skip_secondary || slot_all);
1730 skip(2);
1731 } else {
1732 do_update(transport, "update.zip", slot_override, erase_first, skip_secondary || slot_all);
1733 skip(1);
1734 }
1735 wants_reboot = 1;
1736 } else if(!strcmp(*argv, "set_active")) {
1737 require(2);
1738 std::string slot = verify_slot(transport, std::string(argv[1]), false);
1739 fb_set_active(slot.c_str());
1740 skip(2);
1741 } else if(!strcmp(*argv, "oem")) {
1742 argc = do_oem_command(argc, argv);
1743 } else if(!strcmp(*argv, "flashing")) {
1744 if (argc == 2 && (!strcmp(*(argv+1), "unlock") ||
1745 !strcmp(*(argv+1), "lock") ||
1746 !strcmp(*(argv+1), "unlock_critical") ||
1747 !strcmp(*(argv+1), "lock_critical") ||
1748 !strcmp(*(argv+1), "get_unlock_ability") ||
1749 !strcmp(*(argv+1), "get_unlock_bootloader_nonce") ||
1750 !strcmp(*(argv+1), "lock_bootloader"))) {
1751 argc = do_oem_command(argc, argv);
1752 } else
1753 if (argc == 3 && !strcmp(*(argv+1), "unlock_bootloader")) {
1754 argc = do_bypass_unlock_command(argc, argv);
1755 } else {
1756 usage();
1757 return 1;
1758 }
1759 } else {
1760 usage();
1761 return 1;
1762 }
1763 }
1764
1765 if (wants_wipe) {
1766 fprintf(stderr, "wiping userdata...\n");
1767 fb_queue_erase("userdata");
1768 if (set_fbe_marker) {
1769 fprintf(stderr, "setting FBE marker...\n");
1770 std::string initial_userdata_dir = create_fbemarker_tmpdir();
1771 if (initial_userdata_dir.empty()) {
1772 return 1;
1773 }
1774 fb_perform_format(transport, "userdata", 1, nullptr, nullptr, initial_userdata_dir);
1775 delete_fbemarker_tmpdir(initial_userdata_dir);
1776 } else {
1777 fb_perform_format(transport, "userdata", 1, nullptr, nullptr, "");
1778 }
1779
1780 std::string cache_type;
1781 if (fb_getvar(transport, "partition-type:cache", &cache_type) && !cache_type.empty()) {
1782 fprintf(stderr, "wiping cache...\n");
1783 fb_queue_erase("cache");
1784 fb_perform_format(transport, "cache", 1, nullptr, nullptr, "");
1785 }
1786 }
1787 if (wants_set_active) {
1788 fb_set_active(next_active.c_str());
1789 }
1790 if (wants_reboot) {
1791 fb_queue_reboot();
1792 fb_queue_wait_for_disconnect();
1793 } else if (wants_reboot_bootloader) {
1794 fb_queue_command("reboot-bootloader", "rebooting into bootloader");
1795 fb_queue_wait_for_disconnect();
1796 }
1797
1798 return fb_execute_queue(transport) ? EXIT_FAILURE : EXIT_SUCCESS;
1799 }
1800