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