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