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 <stdbool.h> 38#include <stdint.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <sys/stat.h> 43#include <sys/time.h> 44#include <sys/types.h> 45#include <unistd.h> 46 47#include <bootimg.h> 48#include <sparse/sparse.h> 49#include <zipfile/zipfile.h> 50 51#include "fastboot.h" 52#include "fs.h" 53 54#ifndef O_BINARY 55#define O_BINARY 0 56#endif 57 58#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 59 60char cur_product[FB_RESPONSE_SZ + 1]; 61 62void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline); 63 64boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset, 65 void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset, 66 void *second, unsigned second_size, unsigned second_offset, 67 unsigned page_size, unsigned base, unsigned tags_offset, 68 unsigned *bootimg_size); 69 70static usb_handle *usb = 0; 71static const char *serial = 0; 72static const char *product = 0; 73static const char *cmdline = 0; 74static unsigned short vendor_id = 0; 75static int long_listing = 0; 76static int64_t sparse_limit = -1; 77static int64_t target_sparse_limit = -1; 78 79unsigned page_size = 2048; 80unsigned base_addr = 0x10000000; 81unsigned kernel_offset = 0x00008000; 82unsigned ramdisk_offset = 0x01000000; 83unsigned second_offset = 0x00f00000; 84unsigned tags_offset = 0x00000100; 85 86enum fb_buffer_type { 87 FB_BUFFER, 88 FB_BUFFER_SPARSE, 89}; 90 91struct fastboot_buffer { 92 enum fb_buffer_type type; 93 void *data; 94 unsigned int sz; 95}; 96 97static struct { 98 char img_name[13]; 99 char sig_name[13]; 100 char part_name[9]; 101 bool is_optional; 102} images[] = { 103 {"boot.img", "boot.sig", "boot", false}, 104 {"recovery.img", "recovery.sig", "recovery", true}, 105 {"system.img", "system.sig", "system", false}, 106 {"vendor.img", "vendor.sig", "vendor", true}, 107}; 108 109void get_my_path(char *path); 110 111char *find_item(const char *item, const char *product) 112{ 113 char *dir; 114 char *fn; 115 char path[PATH_MAX + 128]; 116 117 if(!strcmp(item,"boot")) { 118 fn = "boot.img"; 119 } else if(!strcmp(item,"recovery")) { 120 fn = "recovery.img"; 121 } else if(!strcmp(item,"system")) { 122 fn = "system.img"; 123 } else if(!strcmp(item,"vendor")) { 124 fn = "vendor.img"; 125 } else if(!strcmp(item,"userdata")) { 126 fn = "userdata.img"; 127 } else if(!strcmp(item,"cache")) { 128 fn = "cache.img"; 129 } else if(!strcmp(item,"info")) { 130 fn = "android-info.txt"; 131 } else { 132 fprintf(stderr,"unknown partition '%s'\n", item); 133 return 0; 134 } 135 136 if(product) { 137 get_my_path(path); 138 sprintf(path + strlen(path), 139 "../../../target/product/%s/%s", product, fn); 140 return strdup(path); 141 } 142 143 dir = getenv("ANDROID_PRODUCT_OUT"); 144 if((dir == 0) || (dir[0] == 0)) { 145 die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); 146 return 0; 147 } 148 149 sprintf(path, "%s/%s", dir, fn); 150 return strdup(path); 151} 152 153static int64_t file_size(int fd) 154{ 155 struct stat st; 156 int ret; 157 158 ret = fstat(fd, &st); 159 160 return ret ? -1 : st.st_size; 161} 162 163static void *load_fd(int fd, unsigned *_sz) 164{ 165 char *data; 166 int sz; 167 int errno_tmp; 168 169 data = 0; 170 171 sz = file_size(fd); 172 if (sz < 0) { 173 goto oops; 174 } 175 176 data = (char*) malloc(sz); 177 if(data == 0) goto oops; 178 179 if(read(fd, data, sz) != sz) goto oops; 180 close(fd); 181 182 if(_sz) *_sz = sz; 183 return data; 184 185oops: 186 errno_tmp = errno; 187 close(fd); 188 if(data != 0) free(data); 189 errno = errno_tmp; 190 return 0; 191} 192 193static void *load_file(const char *fn, unsigned *_sz) 194{ 195 int fd; 196 197 fd = open(fn, O_RDONLY | O_BINARY); 198 if(fd < 0) return 0; 199 200 return load_fd(fd, _sz); 201} 202 203int match_fastboot_with_serial(usb_ifc_info *info, const char *local_serial) 204{ 205 if(!(vendor_id && (info->dev_vendor == vendor_id)) && 206 (info->dev_vendor != 0x18d1) && // Google 207 (info->dev_vendor != 0x8087) && // Intel 208 (info->dev_vendor != 0x0451) && 209 (info->dev_vendor != 0x0502) && 210 (info->dev_vendor != 0x0fce) && // Sony Ericsson 211 (info->dev_vendor != 0x05c6) && // Qualcomm 212 (info->dev_vendor != 0x22b8) && // Motorola 213 (info->dev_vendor != 0x0955) && // Nvidia 214 (info->dev_vendor != 0x413c) && // DELL 215 (info->dev_vendor != 0x2314) && // INQ Mobile 216 (info->dev_vendor != 0x0b05) && // Asus 217 (info->dev_vendor != 0x0bb4)) // HTC 218 return -1; 219 if(info->ifc_class != 0xff) return -1; 220 if(info->ifc_subclass != 0x42) return -1; 221 if(info->ifc_protocol != 0x03) return -1; 222 // require matching serial number or device path if requested 223 // at the command line with the -s option. 224 if (local_serial && (strcmp(local_serial, info->serial_number) != 0 && 225 strcmp(local_serial, info->device_path) != 0)) return -1; 226 return 0; 227} 228 229int match_fastboot(usb_ifc_info *info) 230{ 231 return match_fastboot_with_serial(info, serial); 232} 233 234int list_devices_callback(usb_ifc_info *info) 235{ 236 if (match_fastboot_with_serial(info, NULL) == 0) { 237 char* serial = info->serial_number; 238 if (!info->writable) { 239 serial = "no permissions"; // like "adb devices" 240 } 241 if (!serial[0]) { 242 serial = "????????????"; 243 } 244 // output compatible with "adb devices" 245 if (!long_listing) { 246 printf("%s\tfastboot\n", serial); 247 } else if (!info->device_path) { 248 printf("%-22s fastboot\n", serial); 249 } else { 250 printf("%-22s fastboot %s\n", serial, info->device_path); 251 } 252 } 253 254 return -1; 255} 256 257usb_handle *open_device(void) 258{ 259 static usb_handle *usb = 0; 260 int announce = 1; 261 262 if(usb) return usb; 263 264 for(;;) { 265 usb = usb_open(match_fastboot); 266 if(usb) return usb; 267 if(announce) { 268 announce = 0; 269 fprintf(stderr,"< waiting for device >\n"); 270 } 271 usleep(1000); 272 } 273} 274 275void list_devices(void) { 276 // We don't actually open a USB device here, 277 // just getting our callback called so we can 278 // list all the connected devices. 279 usb_open(list_devices_callback); 280} 281 282void usage(void) 283{ 284 fprintf(stderr, 285/* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */ 286 "usage: fastboot [ <option> ] <command>\n" 287 "\n" 288 "commands:\n" 289 " update <filename> reflash device from update.zip\n" 290 " flashall flash boot, system, vendor and if found,\n" 291 " recovery\n" 292 " flash <partition> [ <filename> ] write a file to a flash partition\n" 293 " erase <partition> erase a flash partition\n" 294 " format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n" 295 " Can override the fs type and/or\n" 296 " size the bootloader reports.\n" 297 " getvar <variable> display a bootloader variable\n" 298 " boot <kernel> [ <ramdisk> [ <second> ] ] download and boot kernel\n" 299 " flash:raw boot <kernel> [ <ramdisk> [ <second> ] ] create bootimage and \n" 300 " flash it\n" 301 " devices list all connected devices\n" 302 " continue continue with autoboot\n" 303 " reboot reboot device normally\n" 304 " reboot-bootloader reboot device into bootloader\n" 305 " help show this help message\n" 306 "\n" 307 "options:\n" 308 " -w erase userdata and cache (and format\n" 309 " if supported by partition type)\n" 310 " -u do not first erase partition before\n" 311 " formatting\n" 312 " -s <specific device> specify device serial number\n" 313 " or path to device port\n" 314 " -l with \"devices\", lists device paths\n" 315 " -p <product> specify product name\n" 316 " -c <cmdline> override kernel commandline\n" 317 " -i <vendor id> specify a custom USB vendor id\n" 318 " -b <base_addr> specify a custom kernel base address.\n" 319 " default: 0x10000000\n" 320 " -n <page size> specify the nand page size.\n" 321 " default: 2048\n" 322 " -S <size>[K|M|G] automatically sparse files greater\n" 323 " than size. 0 to disable\n" 324 ); 325} 326 327void *load_bootable_image(const char *kernel, const char *ramdisk, 328 const char *secondstage, unsigned *sz, 329 const char *cmdline) 330{ 331 void *kdata = 0, *rdata = 0, *sdata = 0; 332 unsigned ksize = 0, rsize = 0, ssize = 0; 333 void *bdata; 334 unsigned bsize; 335 336 if(kernel == 0) { 337 fprintf(stderr, "no image specified\n"); 338 return 0; 339 } 340 341 kdata = load_file(kernel, &ksize); 342 if(kdata == 0) { 343 fprintf(stderr, "cannot load '%s': %s\n", kernel, strerror(errno)); 344 return 0; 345 } 346 347 /* is this actually a boot image? */ 348 if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { 349 if(cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline); 350 351 if(ramdisk) { 352 fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n"); 353 return 0; 354 } 355 356 *sz = ksize; 357 return kdata; 358 } 359 360 if(ramdisk) { 361 rdata = load_file(ramdisk, &rsize); 362 if(rdata == 0) { 363 fprintf(stderr,"cannot load '%s': %s\n", ramdisk, strerror(errno)); 364 return 0; 365 } 366 } 367 368 if (secondstage) { 369 sdata = load_file(secondstage, &ssize); 370 if(sdata == 0) { 371 fprintf(stderr,"cannot load '%s': %s\n", secondstage, strerror(errno)); 372 return 0; 373 } 374 } 375 376 fprintf(stderr,"creating boot image...\n"); 377 bdata = mkbootimg(kdata, ksize, kernel_offset, 378 rdata, rsize, ramdisk_offset, 379 sdata, ssize, second_offset, 380 page_size, base_addr, tags_offset, &bsize); 381 if(bdata == 0) { 382 fprintf(stderr,"failed to create boot.img\n"); 383 return 0; 384 } 385 if(cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline); 386 fprintf(stderr,"creating boot image - %d bytes\n", bsize); 387 *sz = bsize; 388 389 return bdata; 390} 391 392void *unzip_file(zipfile_t zip, const char *name, unsigned *sz) 393{ 394 void *data; 395 zipentry_t entry; 396 unsigned datasz; 397 398 entry = lookup_zipentry(zip, name); 399 if (entry == NULL) { 400 fprintf(stderr, "archive does not contain '%s'\n", name); 401 return 0; 402 } 403 404 *sz = get_zipentry_size(entry); 405 406 datasz = *sz * 1.001; 407 data = malloc(datasz); 408 409 if(data == 0) { 410 fprintf(stderr, "failed to allocate %d bytes\n", *sz); 411 return 0; 412 } 413 414 if (decompress_zipentry(entry, data, datasz)) { 415 fprintf(stderr, "failed to unzip '%s' from archive\n", name); 416 free(data); 417 return 0; 418 } 419 420 return data; 421} 422 423static int unzip_to_file(zipfile_t zip, char *name) 424{ 425 int fd; 426 char *data; 427 unsigned sz; 428 429 fd = fileno(tmpfile()); 430 if (fd < 0) { 431 return -1; 432 } 433 434 data = unzip_file(zip, name, &sz); 435 if (data == 0) { 436 return -1; 437 } 438 439 if (write(fd, data, sz) != (ssize_t)sz) { 440 fd = -1; 441 } 442 443 free(data); 444 lseek(fd, 0, SEEK_SET); 445 return fd; 446} 447 448static char *strip(char *s) 449{ 450 int n; 451 while(*s && isspace(*s)) s++; 452 n = strlen(s); 453 while(n-- > 0) { 454 if(!isspace(s[n])) break; 455 s[n] = 0; 456 } 457 return s; 458} 459 460#define MAX_OPTIONS 32 461static int setup_requirement_line(char *name) 462{ 463 char *val[MAX_OPTIONS]; 464 const char **out; 465 char *prod = NULL; 466 unsigned n, count; 467 char *x; 468 int invert = 0; 469 470 if (!strncmp(name, "reject ", 7)) { 471 name += 7; 472 invert = 1; 473 } else if (!strncmp(name, "require ", 8)) { 474 name += 8; 475 invert = 0; 476 } else if (!strncmp(name, "require-for-product:", 20)) { 477 // Get the product and point name past it 478 prod = name + 20; 479 name = strchr(name, ' '); 480 if (!name) return -1; 481 *name = 0; 482 name += 1; 483 invert = 0; 484 } 485 486 x = strchr(name, '='); 487 if (x == 0) return 0; 488 *x = 0; 489 val[0] = x + 1; 490 491 for(count = 1; count < MAX_OPTIONS; count++) { 492 x = strchr(val[count - 1],'|'); 493 if (x == 0) break; 494 *x = 0; 495 val[count] = x + 1; 496 } 497 498 name = strip(name); 499 for(n = 0; n < count; n++) val[n] = strip(val[n]); 500 501 name = strip(name); 502 if (name == 0) return -1; 503 504 /* work around an unfortunate name mismatch */ 505 if (!strcmp(name,"board")) name = "product"; 506 507 out = malloc(sizeof(char*) * count); 508 if (out == 0) return -1; 509 510 for(n = 0; n < count; n++) { 511 out[n] = strdup(strip(val[n])); 512 if (out[n] == 0) { 513 for(size_t i = 0; i < n; ++i) { 514 free((char*) out[i]); 515 } 516 free(out); 517 return -1; 518 } 519 } 520 521 fb_queue_require(prod, name, invert, n, out); 522 return 0; 523} 524 525static void setup_requirements(char *data, unsigned sz) 526{ 527 char *s; 528 529 s = data; 530 while (sz-- > 0) { 531 if(*s == '\n') { 532 *s++ = 0; 533 if (setup_requirement_line(data)) { 534 die("out of memory"); 535 } 536 data = s; 537 } else { 538 s++; 539 } 540 } 541} 542 543void queue_info_dump(void) 544{ 545 fb_queue_notice("--------------------------------------------"); 546 fb_queue_display("version-bootloader", "Bootloader Version..."); 547 fb_queue_display("version-baseband", "Baseband Version....."); 548 fb_queue_display("serialno", "Serial Number........"); 549 fb_queue_notice("--------------------------------------------"); 550} 551 552static struct sparse_file **load_sparse_files(int fd, int max_size) 553{ 554 struct sparse_file *s; 555 int files; 556 struct sparse_file **out_s; 557 558 s = sparse_file_import_auto(fd, false); 559 if (!s) { 560 die("cannot sparse read file\n"); 561 } 562 563 files = sparse_file_resparse(s, max_size, NULL, 0); 564 if (files < 0) { 565 die("Failed to resparse\n"); 566 } 567 568 out_s = calloc(sizeof(struct sparse_file *), files + 1); 569 if (!out_s) { 570 die("Failed to allocate sparse file array\n"); 571 } 572 573 files = sparse_file_resparse(s, max_size, out_s, files); 574 if (files < 0) { 575 die("Failed to resparse\n"); 576 } 577 578 return out_s; 579} 580 581static int64_t get_target_sparse_limit(struct usb_handle *usb) 582{ 583 int64_t limit = 0; 584 char response[FB_RESPONSE_SZ + 1]; 585 int status = fb_getvar(usb, response, "max-download-size"); 586 587 if (!status) { 588 limit = strtoul(response, NULL, 0); 589 if (limit > 0) { 590 fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", 591 limit); 592 } 593 } 594 595 return limit; 596} 597 598static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size) 599{ 600 int64_t limit; 601 602 if (sparse_limit == 0) { 603 return 0; 604 } else if (sparse_limit > 0) { 605 limit = sparse_limit; 606 } else { 607 if (target_sparse_limit == -1) { 608 target_sparse_limit = get_target_sparse_limit(usb); 609 } 610 if (target_sparse_limit > 0) { 611 limit = target_sparse_limit; 612 } else { 613 return 0; 614 } 615 } 616 617 if (size > limit) { 618 return limit; 619 } 620 621 return 0; 622} 623 624/* Until we get lazy inode table init working in make_ext4fs, we need to 625 * erase partitions of type ext4 before flashing a filesystem so no stale 626 * inodes are left lying around. Otherwise, e2fsck gets very upset. 627 */ 628static int needs_erase(const char *part) 629{ 630 /* The function fb_format_supported() currently returns the value 631 * we want, so just call it. 632 */ 633 return fb_format_supported(usb, part, NULL); 634} 635 636static int load_buf_fd(usb_handle *usb, int fd, 637 struct fastboot_buffer *buf) 638{ 639 int64_t sz64; 640 void *data; 641 int64_t limit; 642 643 644 sz64 = file_size(fd); 645 if (sz64 < 0) { 646 return -1; 647 } 648 649 lseek(fd, 0, SEEK_SET); 650 limit = get_sparse_limit(usb, sz64); 651 if (limit) { 652 struct sparse_file **s = load_sparse_files(fd, limit); 653 if (s == NULL) { 654 return -1; 655 } 656 buf->type = FB_BUFFER_SPARSE; 657 buf->data = s; 658 } else { 659 unsigned int sz; 660 data = load_fd(fd, &sz); 661 if (data == 0) return -1; 662 buf->type = FB_BUFFER; 663 buf->data = data; 664 buf->sz = sz; 665 } 666 667 return 0; 668} 669 670static int load_buf(usb_handle *usb, const char *fname, 671 struct fastboot_buffer *buf) 672{ 673 int fd; 674 675 fd = open(fname, O_RDONLY | O_BINARY); 676 if (fd < 0) { 677 return -1; 678 } 679 680 return load_buf_fd(usb, fd, buf); 681} 682 683static void flash_buf(const char *pname, struct fastboot_buffer *buf) 684{ 685 struct sparse_file **s; 686 687 switch (buf->type) { 688 case FB_BUFFER_SPARSE: 689 s = buf->data; 690 while (*s) { 691 int64_t sz64 = sparse_file_len(*s, true, false); 692 fb_queue_flash_sparse(pname, *s++, sz64); 693 } 694 break; 695 case FB_BUFFER: 696 fb_queue_flash(pname, buf->data, buf->sz); 697 break; 698 default: 699 die("unknown buffer type: %d", buf->type); 700 } 701} 702 703void do_flash(usb_handle *usb, const char *pname, const char *fname) 704{ 705 struct fastboot_buffer buf; 706 707 if (load_buf(usb, fname, &buf)) { 708 die("cannot load '%s'", fname); 709 } 710 flash_buf(pname, &buf); 711} 712 713void do_update_signature(zipfile_t zip, char *fn) 714{ 715 void *data; 716 unsigned sz; 717 data = unzip_file(zip, fn, &sz); 718 if (data == 0) return; 719 fb_queue_download("signature", data, sz); 720 fb_queue_command("signature", "installing signature"); 721} 722 723void do_update(usb_handle *usb, char *fn, int erase_first) 724{ 725 void *zdata; 726 unsigned zsize; 727 void *data; 728 unsigned sz; 729 zipfile_t zip; 730 int fd; 731 int rc; 732 struct fastboot_buffer buf; 733 size_t i; 734 735 queue_info_dump(); 736 737 fb_queue_query_save("product", cur_product, sizeof(cur_product)); 738 739 zdata = load_file(fn, &zsize); 740 if (zdata == 0) die("failed to load '%s': %s", fn, strerror(errno)); 741 742 zip = init_zipfile(zdata, zsize); 743 if(zip == 0) die("failed to access zipdata in '%s'"); 744 745 data = unzip_file(zip, "android-info.txt", &sz); 746 if (data == 0) { 747 char *tmp; 748 /* fallback for older zipfiles */ 749 data = unzip_file(zip, "android-product.txt", &sz); 750 if ((data == 0) || (sz < 1)) { 751 die("update package has no android-info.txt or android-product.txt"); 752 } 753 tmp = malloc(sz + 128); 754 if (tmp == 0) die("out of memory"); 755 sprintf(tmp,"board=%sversion-baseband=0.66.04.19\n",(char*)data); 756 data = tmp; 757 sz = strlen(tmp); 758 } 759 760 setup_requirements(data, sz); 761 762 for (i = 0; i < ARRAY_SIZE(images); i++) { 763 fd = unzip_to_file(zip, images[i].img_name); 764 if (fd < 0) { 765 if (images[i].is_optional) 766 continue; 767 die("update package missing %s", images[i].img_name); 768 } 769 rc = load_buf_fd(usb, fd, &buf); 770 if (rc) die("cannot load %s from flash", images[i].img_name); 771 do_update_signature(zip, images[i].sig_name); 772 if (erase_first && needs_erase(images[i].part_name)) { 773 fb_queue_erase(images[i].part_name); 774 } 775 flash_buf(images[i].part_name, &buf); 776 /* not closing the fd here since the sparse code keeps the fd around 777 * but hasn't mmaped data yet. The tmpfile will get cleaned up when the 778 * program exits. 779 */ 780 } 781} 782 783void do_send_signature(char *fn) 784{ 785 void *data; 786 unsigned sz; 787 char *xtn; 788 789 xtn = strrchr(fn, '.'); 790 if (!xtn) return; 791 if (strcmp(xtn, ".img")) return; 792 793 strcpy(xtn,".sig"); 794 data = load_file(fn, &sz); 795 strcpy(xtn,".img"); 796 if (data == 0) return; 797 fb_queue_download("signature", data, sz); 798 fb_queue_command("signature", "installing signature"); 799} 800 801void do_flashall(usb_handle *usb, int erase_first) 802{ 803 char *fname; 804 void *data; 805 unsigned sz; 806 struct fastboot_buffer buf; 807 size_t i; 808 809 queue_info_dump(); 810 811 fb_queue_query_save("product", cur_product, sizeof(cur_product)); 812 813 fname = find_item("info", product); 814 if (fname == 0) die("cannot find android-info.txt"); 815 data = load_file(fname, &sz); 816 if (data == 0) die("could not load android-info.txt: %s", strerror(errno)); 817 setup_requirements(data, sz); 818 819 for (i = 0; i < ARRAY_SIZE(images); i++) { 820 fname = find_item(images[i].part_name, product); 821 if (load_buf(usb, fname, &buf)) { 822 if (images[i].is_optional) 823 continue; 824 die("could not load %s\n", images[i].img_name); 825 } 826 do_send_signature(fname); 827 if (erase_first && needs_erase(images[i].part_name)) { 828 fb_queue_erase(images[i].part_name); 829 } 830 flash_buf(images[i].part_name, &buf); 831 } 832} 833 834#define skip(n) do { argc -= (n); argv += (n); } while (0) 835#define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0) 836 837int do_oem_command(int argc, char **argv) 838{ 839 char command[256]; 840 if (argc <= 1) return 0; 841 842 command[0] = 0; 843 while(1) { 844 strcat(command,*argv); 845 skip(1); 846 if(argc == 0) break; 847 strcat(command," "); 848 } 849 850 fb_queue_command(command,""); 851 return 0; 852} 853 854static int64_t parse_num(const char *arg) 855{ 856 char *endptr; 857 unsigned long long num; 858 859 num = strtoull(arg, &endptr, 0); 860 if (endptr == arg) { 861 return -1; 862 } 863 864 if (*endptr == 'k' || *endptr == 'K') { 865 if (num >= (-1ULL) / 1024) { 866 return -1; 867 } 868 num *= 1024LL; 869 endptr++; 870 } else if (*endptr == 'm' || *endptr == 'M') { 871 if (num >= (-1ULL) / (1024 * 1024)) { 872 return -1; 873 } 874 num *= 1024LL * 1024LL; 875 endptr++; 876 } else if (*endptr == 'g' || *endptr == 'G') { 877 if (num >= (-1ULL) / (1024 * 1024 * 1024)) { 878 return -1; 879 } 880 num *= 1024LL * 1024LL * 1024LL; 881 endptr++; 882 } 883 884 if (*endptr != '\0') { 885 return -1; 886 } 887 888 if (num > INT64_MAX) { 889 return -1; 890 } 891 892 return num; 893} 894 895void fb_perform_format(const char *partition, int skip_if_not_supported, 896 const char *type_override, const char *size_override) 897{ 898 char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1]; 899 char *pType = pTypeBuff; 900 char *pSize = pSizeBuff; 901 unsigned int limit = INT_MAX; 902 struct fastboot_buffer buf; 903 const char *errMsg = NULL; 904 const struct fs_generator *gen; 905 uint64_t pSz; 906 int status; 907 int fd; 908 909 if (target_sparse_limit > 0 && target_sparse_limit < limit) 910 limit = target_sparse_limit; 911 if (sparse_limit > 0 && sparse_limit < limit) 912 limit = sparse_limit; 913 914 status = fb_getvar(usb, pType, "partition-type:%s", partition); 915 if (status) { 916 errMsg = "Can't determine partition type.\n"; 917 goto failed; 918 } 919 if (type_override) { 920 if (strcmp(type_override, pType)) { 921 fprintf(stderr, 922 "Warning: %s type is %s, but %s was requested for formating.\n", 923 partition, pType, type_override); 924 } 925 pType = (char *)type_override; 926 } 927 928 status = fb_getvar(usb, pSize, "partition-size:%s", partition); 929 if (status) { 930 errMsg = "Unable to get partition size\n"; 931 goto failed; 932 } 933 if (size_override) { 934 if (strcmp(size_override, pSize)) { 935 fprintf(stderr, 936 "Warning: %s size is %s, but %s was requested for formating.\n", 937 partition, pSize, size_override); 938 } 939 pSize = (char *)size_override; 940 } 941 942 gen = fs_get_generator(pType); 943 if (!gen) { 944 if (skip_if_not_supported) { 945 fprintf(stderr, "Erase successful, but not automatically formatting.\n"); 946 fprintf(stderr, "File system type %s not supported.\n", pType); 947 return; 948 } 949 fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType); 950 return; 951 } 952 953 pSz = strtoll(pSize, (char **)NULL, 16); 954 955 fd = fileno(tmpfile()); 956 if (fs_generator_generate(gen, fd, pSz)) { 957 close(fd); 958 fprintf(stderr, "Cannot generate image.\n"); 959 return; 960 } 961 962 if (load_buf_fd(usb, fd, &buf)) { 963 fprintf(stderr, "Cannot read image.\n"); 964 close(fd); 965 return; 966 } 967 flash_buf(partition, &buf); 968 969 return; 970 971 972failed: 973 if (skip_if_not_supported) { 974 fprintf(stderr, "Erase successful, but not automatically formatting.\n"); 975 if (errMsg) 976 fprintf(stderr, "%s", errMsg); 977 } 978 fprintf(stderr,"FAILED (%s)\n", fb_get_error()); 979} 980 981int main(int argc, char **argv) 982{ 983 int wants_wipe = 0; 984 int wants_reboot = 0; 985 int wants_reboot_bootloader = 0; 986 int erase_first = 1; 987 void *data; 988 unsigned sz; 989 int status; 990 int c; 991 992 const struct option longopts[] = { 993 {"base", required_argument, 0, 'b'}, 994 {"kernel_offset", required_argument, 0, 'k'}, 995 {"page_size", required_argument, 0, 'n'}, 996 {"ramdisk_offset", required_argument, 0, 'r'}, 997 {"tags_offset", required_argument, 0, 't'}, 998 {"help", 0, 0, 'h'}, 999 {0, 0, 0, 0} 1000 }; 1001 1002 serial = getenv("ANDROID_SERIAL"); 1003 1004 while (1) { 1005 c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, NULL); 1006 if (c < 0) { 1007 break; 1008 } 1009 /* Alphabetical cases */ 1010 switch (c) { 1011 case 'b': 1012 base_addr = strtoul(optarg, 0, 16); 1013 break; 1014 case 'c': 1015 cmdline = optarg; 1016 break; 1017 case 'h': 1018 usage(); 1019 return 1; 1020 case 'i': { 1021 char *endptr = NULL; 1022 unsigned long val; 1023 1024 val = strtoul(optarg, &endptr, 0); 1025 if (!endptr || *endptr != '\0' || (val & ~0xffff)) 1026 die("invalid vendor id '%s'", optarg); 1027 vendor_id = (unsigned short)val; 1028 break; 1029 } 1030 case 'k': 1031 kernel_offset = strtoul(optarg, 0, 16); 1032 break; 1033 case 'l': 1034 long_listing = 1; 1035 break; 1036 case 'n': 1037 page_size = (unsigned)strtoul(optarg, NULL, 0); 1038 if (!page_size) die("invalid page size"); 1039 break; 1040 case 'p': 1041 product = optarg; 1042 break; 1043 case 'r': 1044 ramdisk_offset = strtoul(optarg, 0, 16); 1045 break; 1046 case 't': 1047 tags_offset = strtoul(optarg, 0, 16); 1048 break; 1049 case 's': 1050 serial = optarg; 1051 break; 1052 case 'S': 1053 sparse_limit = parse_num(optarg); 1054 if (sparse_limit < 0) { 1055 die("invalid sparse limit"); 1056 } 1057 break; 1058 case 'u': 1059 erase_first = 0; 1060 break; 1061 case 'w': 1062 wants_wipe = 1; 1063 break; 1064 case '?': 1065 return 1; 1066 default: 1067 abort(); 1068 } 1069 } 1070 1071 argc -= optind; 1072 argv += optind; 1073 1074 if (argc == 0 && !wants_wipe) { 1075 usage(); 1076 return 1; 1077 } 1078 1079 if (argc > 0 && !strcmp(*argv, "devices")) { 1080 skip(1); 1081 list_devices(); 1082 return 0; 1083 } 1084 1085 if (argc > 0 && !strcmp(*argv, "help")) { 1086 usage(); 1087 return 0; 1088 } 1089 1090 usb = open_device(); 1091 1092 while (argc > 0) { 1093 if(!strcmp(*argv, "getvar")) { 1094 require(2); 1095 fb_queue_display(argv[1], argv[1]); 1096 skip(2); 1097 } else if(!strcmp(*argv, "erase")) { 1098 require(2); 1099 1100 if (fb_format_supported(usb, argv[1], NULL)) { 1101 fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); 1102 } 1103 1104 fb_queue_erase(argv[1]); 1105 skip(2); 1106 } else if(!strncmp(*argv, "format", strlen("format"))) { 1107 char *overrides; 1108 char *type_override = NULL; 1109 char *size_override = NULL; 1110 require(2); 1111 /* 1112 * Parsing for: "format[:[type][:[size]]]" 1113 * Some valid things: 1114 * - select ontly the size, and leave default fs type: 1115 * format::0x4000000 userdata 1116 * - default fs type and size: 1117 * format userdata 1118 * format:: userdata 1119 */ 1120 overrides = strchr(*argv, ':'); 1121 if (overrides) { 1122 overrides++; 1123 size_override = strchr(overrides, ':'); 1124 if (size_override) { 1125 size_override[0] = '\0'; 1126 size_override++; 1127 } 1128 type_override = overrides; 1129 } 1130 if (type_override && !type_override[0]) type_override = NULL; 1131 if (size_override && !size_override[0]) size_override = NULL; 1132 if (erase_first && needs_erase(argv[1])) { 1133 fb_queue_erase(argv[1]); 1134 } 1135 fb_perform_format(argv[1], 0, type_override, size_override); 1136 skip(2); 1137 } else if(!strcmp(*argv, "signature")) { 1138 require(2); 1139 data = load_file(argv[1], &sz); 1140 if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno)); 1141 if (sz != 256) die("signature must be 256 bytes"); 1142 fb_queue_download("signature", data, sz); 1143 fb_queue_command("signature", "installing signature"); 1144 skip(2); 1145 } else if(!strcmp(*argv, "reboot")) { 1146 wants_reboot = 1; 1147 skip(1); 1148 } else if(!strcmp(*argv, "reboot-bootloader")) { 1149 wants_reboot_bootloader = 1; 1150 skip(1); 1151 } else if (!strcmp(*argv, "continue")) { 1152 fb_queue_command("continue", "resuming boot"); 1153 skip(1); 1154 } else if(!strcmp(*argv, "boot")) { 1155 char *kname = 0; 1156 char *rname = 0; 1157 char *sname = 0; 1158 skip(1); 1159 if (argc > 0) { 1160 kname = argv[0]; 1161 skip(1); 1162 } 1163 if (argc > 0) { 1164 rname = argv[0]; 1165 skip(1); 1166 } 1167 if (argc > 0) { 1168 sname = argv[0]; 1169 skip(1); 1170 } 1171 data = load_bootable_image(kname, rname, sname, &sz, cmdline); 1172 if (data == 0) return 1; 1173 fb_queue_download("boot.img", data, sz); 1174 fb_queue_command("boot", "booting"); 1175 } else if(!strcmp(*argv, "flash")) { 1176 char *pname = argv[1]; 1177 char *fname = 0; 1178 require(2); 1179 if (argc > 2) { 1180 fname = argv[2]; 1181 skip(3); 1182 } else { 1183 fname = find_item(pname, product); 1184 skip(2); 1185 } 1186 if (fname == 0) die("cannot determine image filename for '%s'", pname); 1187 if (erase_first && needs_erase(pname)) { 1188 fb_queue_erase(pname); 1189 } 1190 do_flash(usb, pname, fname); 1191 } else if(!strcmp(*argv, "flash:raw")) { 1192 char *pname = argv[1]; 1193 char *kname = argv[2]; 1194 char *rname = 0; 1195 char *sname = 0; 1196 require(3); 1197 skip(3); 1198 if (argc > 0) { 1199 rname = argv[0]; 1200 skip(1); 1201 } 1202 if (argc > 0) { 1203 sname = argv[0]; 1204 skip(1); 1205 } 1206 data = load_bootable_image(kname, rname, sname, &sz, cmdline); 1207 if (data == 0) die("cannot load bootable image"); 1208 fb_queue_flash(pname, data, sz); 1209 } else if(!strcmp(*argv, "flashall")) { 1210 skip(1); 1211 do_flashall(usb, erase_first); 1212 wants_reboot = 1; 1213 } else if(!strcmp(*argv, "update")) { 1214 if (argc > 1) { 1215 do_update(usb, argv[1], erase_first); 1216 skip(2); 1217 } else { 1218 do_update(usb, "update.zip", erase_first); 1219 skip(1); 1220 } 1221 wants_reboot = 1; 1222 } else if(!strcmp(*argv, "oem")) { 1223 argc = do_oem_command(argc, argv); 1224 } else { 1225 usage(); 1226 return 1; 1227 } 1228 } 1229 1230 if (wants_wipe) { 1231 fb_queue_erase("userdata"); 1232 fb_perform_format("userdata", 1, NULL, NULL); 1233 fb_queue_erase("cache"); 1234 fb_perform_format("cache", 1, NULL, NULL); 1235 } 1236 if (wants_reboot) { 1237 fb_queue_reboot(); 1238 fb_queue_wait_for_disconnect(); 1239 } else if (wants_reboot_bootloader) { 1240 fb_queue_command("reboot-bootloader", "rebooting into bootloader"); 1241 fb_queue_wait_for_disconnect(); 1242 } 1243 1244 if (fb_queue_is_empty()) 1245 return 0; 1246 1247 status = fb_execute_queue(usb); 1248 return (status) ? 1 : 0; 1249} 1250