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