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