diff options
Diffstat (limited to 'fastboot/fastboot.c')
-rw-r--r-- | fastboot/fastboot.c | 124 |
1 files changed, 88 insertions, 36 deletions
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c index 4fd1a8e..266d0b5 100644 --- a/fastboot/fastboot.c +++ b/fastboot/fastboot.c @@ -28,21 +28,21 @@ #define _LARGEFILE64_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <stdint.h> -#include <string.h> +#include <ctype.h> #include <errno.h> #include <fcntl.h> -#include <unistd.h> -#include <limits.h> -#include <ctype.h> #include <getopt.h> - +#include <inttypes.h> +#include <limits.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> #include <sys/time.h> #include <sys/types.h> -#include <sys/stat.h> +#include <unistd.h> #include <bootimg.h> #include <sparse/sparse.h> @@ -71,7 +71,6 @@ static usb_handle *usb = 0; static const char *serial = 0; static const char *product = 0; static const char *cmdline = 0; -static int wipe_data = 0; static unsigned short vendor_id = 0; static int long_listing = 0; static int64_t sparse_limit = -1; @@ -100,10 +99,11 @@ static struct { char sig_name[13]; char part_name[9]; bool is_optional; -} images[3] = { +} images[4] = { {"boot.img", "boot.sig", "boot", false}, {"recovery.img", "recovery.sig", "recovery", true}, {"system.img", "system.sig", "system", false}, + {"tos.img", "tos.sig", "tos", true}, }; void get_my_path(char *path); @@ -120,6 +120,8 @@ char *find_item(const char *item, const char *product) fn = "recovery.img"; } else if(!strcmp(item,"system")) { fn = "system.img"; + } else if(!strcmp(item,"tos")) { + fn = "tos.img"; } else if(!strcmp(item,"userdata")) { fn = "userdata.img"; } else if(!strcmp(item,"cache")) { @@ -266,7 +268,7 @@ usb_handle *open_device(void) announce = 0; fprintf(stderr,"< waiting for device >\n"); } - sleep(1); + usleep(1000); } } @@ -285,10 +287,13 @@ void usage(void) "\n" "commands:\n" " update <filename> reflash device from update.zip\n" - " flashall flash boot + recovery + system\n" + " flashall flash boot, system, and if found,\n" + " recovery, tos\n" " flash <partition> [ <filename> ] write a file to a flash partition\n" " erase <partition> erase a flash partition\n" - " format <partition> format a flash partition \n" + " format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n" + " Can override the fs type and/or\n" + " size the bootloader reports.\n" " getvar <variable> display a bootloader variable\n" " boot <kernel> [ <ramdisk> ] download and boot kernel\n" " flash:raw boot <kernel> [ <ramdisk> ] create bootimage and flash it\n" @@ -309,10 +314,12 @@ void usage(void) " -p <product> specify product name\n" " -c <cmdline> override kernel commandline\n" " -i <vendor id> specify a custom USB vendor id\n" - " -b <base_addr> specify a custom kernel base address. default: 0x10000000\n" - " -n <page size> specify the nand page size. default: 2048\n" - " -S <size>[K|M|G] automatically sparse files greater than\n" - " size. 0 to disable\n" + " -b <base_addr> specify a custom kernel base address.\n" + " default: 0x10000000\n" + " -n <page size> specify the nand page size.\n" + " default: 2048\n" + " -S <size>[K|M|G] automatically sparse files greater\n" + " than size. 0 to disable\n" ); } @@ -419,7 +426,7 @@ static int unzip_to_file(zipfile_t zip, char *name) return -1; } - if (write(fd, data, sz) != sz) { + if (write(fd, data, sz) != (ssize_t)sz) { fd = -1; } @@ -570,7 +577,7 @@ static int64_t get_target_sparse_limit(struct usb_handle *usb) if (!status) { limit = strtoul(response, NULL, 0); if (limit > 0) { - fprintf(stderr, "target reported max download size of %lld bytes\n", + fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit); } } @@ -613,7 +620,7 @@ static int needs_erase(const char *part) /* The function fb_format_supported() currently returns the value * we want, so just call it. */ - return fb_format_supported(usb, part); + return fb_format_supported(usb, part, NULL); } static int load_buf_fd(usb_handle *usb, int fd, @@ -657,7 +664,7 @@ static int load_buf(usb_handle *usb, const char *fname, fd = open(fname, O_RDONLY | O_BINARY); if (fd < 0) { - die("cannot open '%s'\n", fname); + return -1; } return load_buf_fd(usb, fd, buf); @@ -713,7 +720,7 @@ void do_update(usb_handle *usb, char *fn, int erase_first) int fd; int rc; struct fastboot_buffer buf; - int i; + size_t i; queue_info_dump(); @@ -787,7 +794,7 @@ void do_flashall(usb_handle *usb, int erase_first) void *data; unsigned sz; struct fastboot_buffer buf; - int i; + size_t i; queue_info_dump(); @@ -819,7 +826,6 @@ void do_flashall(usb_handle *usb, int erase_first) int do_oem_command(int argc, char **argv) { - int i; char command[256]; if (argc <= 1) return 0; @@ -876,9 +882,12 @@ static int64_t parse_num(const char *arg) return num; } -void fb_perform_format(const char *partition, int skip_if_not_supported) +void fb_perform_format(const char *partition, int skip_if_not_supported, + const char *type_override, const char *size_override) { - char pType[FB_RESPONSE_SZ + 1], pSize[FB_RESPONSE_SZ + 1]; + char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1]; + char *pType = pTypeBuff; + char *pSize = pSizeBuff; unsigned int limit = INT_MAX; struct fastboot_buffer buf; const char *errMsg = NULL; @@ -897,12 +906,28 @@ void fb_perform_format(const char *partition, int skip_if_not_supported) errMsg = "Can't determine partition type.\n"; goto failed; } + if (type_override) { + if (strcmp(type_override, pType)) { + fprintf(stderr, + "Warning: %s type is %s, but %s was requested for formating.\n", + partition, pType, type_override); + } + pType = (char *)type_override; + } status = fb_getvar(usb, pSize, "partition-size:%s", partition); if (status) { errMsg = "Unable to get partition size\n"; goto failed; } + if (size_override) { + if (strcmp(size_override, pSize)) { + fprintf(stderr, + "Warning: %s size is %s, but %s was requested for formating.\n", + partition, pSize, size_override); + } + pSize = (char *)size_override; + } gen = fs_get_generator(pType); if (!gen) { @@ -953,13 +978,13 @@ int main(int argc, char **argv) unsigned sz; int status; int c; - int r; const struct option longopts[] = { {"base", required_argument, 0, 'b'}, {"kernel_offset", required_argument, 0, 'k'}, {"page_size", required_argument, 0, 'n'}, {"ramdisk_offset", required_argument, 0, 'r'}, + {"tags_offset", required_argument, 0, 't'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; @@ -967,8 +992,7 @@ int main(int argc, char **argv) serial = getenv("ANDROID_SERIAL"); while (1) { - int option_index = 0; - c = getopt_long(argc, argv, "wub:k:n:r:s:S:lp:c:i:m:h", longopts, NULL); + c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, NULL); if (c < 0) { break; } @@ -1009,6 +1033,9 @@ int main(int argc, char **argv) case 'r': ramdisk_offset = strtoul(optarg, 0, 16); break; + case 't': + tags_offset = strtoul(optarg, 0, 16); + break; case 's': serial = optarg; break; @@ -1060,18 +1087,42 @@ int main(int argc, char **argv) } else if(!strcmp(*argv, "erase")) { require(2); - if (fb_format_supported(usb, argv[1])) { + if (fb_format_supported(usb, argv[1], NULL)) { fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); } fb_queue_erase(argv[1]); skip(2); - } else if(!strcmp(*argv, "format")) { + } else if(!strncmp(*argv, "format", strlen("format"))) { + char *overrides; + char *type_override = NULL; + char *size_override = NULL; require(2); + /* + * Parsing for: "format[:[type][:[size]]]" + * Some valid things: + * - select ontly the size, and leave default fs type: + * format::0x4000000 userdata + * - default fs type and size: + * format userdata + * format:: userdata + */ + overrides = strchr(*argv, ':'); + if (overrides) { + overrides++; + size_override = strchr(overrides, ':'); + if (size_override) { + size_override[0] = '\0'; + size_override++; + } + type_override = overrides; + } + if (type_override && !type_override[0]) type_override = NULL; + if (size_override && !size_override[0]) size_override = NULL; if (erase_first && needs_erase(argv[1])) { fb_queue_erase(argv[1]); } - fb_perform_format(argv[1], 0); + fb_perform_format(argv[1], 0, type_override, size_override); skip(2); } else if(!strcmp(*argv, "signature")) { require(2); @@ -1159,12 +1210,13 @@ int main(int argc, char **argv) if (wants_wipe) { fb_queue_erase("userdata"); - fb_perform_format("userdata", 1); + fb_perform_format("userdata", 1, NULL, NULL); fb_queue_erase("cache"); - fb_perform_format("cache", 1); + fb_perform_format("cache", 1, NULL, NULL); } if (wants_reboot) { fb_queue_reboot(); + fb_queue_wait_for_disconnect(); } else if (wants_reboot_bootloader) { fb_queue_command("reboot-bootloader", "rebooting into bootloader"); fb_queue_wait_for_disconnect(); |