fastboot.cpp revision ec25e7bc4bb8c203f89f133136a62a08410d6ceb
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * All rights reserved. 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met: 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * * Redistributions of source code must retain the above copyright 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer. 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer in 12ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang * the documentation and/or other materials provided with the 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distribution. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE. 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross#define _LARGEFILE64_SOURCE 30f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 315957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <ctype.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 348879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross#include <getopt.h> 35cf86e2f85d98ed10cf5e0672e41631f6ea7e3e34Ying Wang#include <inttypes.h> 365957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <limits.h> 375957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <stdbool.h> 385957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <stdint.h> 395957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <stdio.h> 405957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <stdlib.h> 415957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <string.h> 425957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <sys/stat.h> 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/time.h> 44f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross#include <sys/types.h> 455957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <unistd.h> 46f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <bootimg.h> 48f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross#include <sparse/sparse.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <zipfile/zipfile.h> 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "fastboot.h" 52e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg#include "fs.h" 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 54f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross#ifndef O_BINARY 55f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross#define O_BINARY 0 56f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross#endif 57f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 58622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 59622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 60b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savillechar cur_product[FB_RESPONSE_SZ + 1]; 61b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 622a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandvoid bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline); 632a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland 647b8970c577c788c9af582dac797c63b3134b201eJP Abgrallboot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset, 657b8970c577c788c9af582dac797c63b3134b201eJP Abgrall void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset, 667b8970c577c788c9af582dac797c63b3134b201eJP Abgrall void *second, unsigned second_size, unsigned second_offset, 677b8970c577c788c9af582dac797c63b3134b201eJP Abgrall unsigned page_size, unsigned base, unsigned tags_offset, 682a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland unsigned *bootimg_size); 692a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic usb_handle *usb = 0; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *serial = 0; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *product = 0; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *cmdline = 0; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic unsigned short vendor_id = 0; 7513081c6915220db03886b177f1a8e0b2c63467c9Scott Andersonstatic int long_listing = 0; 76f838788e6a4d57634a53eb597ee76a597feffcb5Colin Crossstatic int64_t sparse_limit = -1; 77f838788e6a4d57634a53eb597ee76a597feffcb5Colin Crossstatic int64_t target_sparse_limit = -1; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 797b8970c577c788c9af582dac797c63b3134b201eJP Abgrallunsigned page_size = 2048; 807b8970c577c788c9af582dac797c63b3134b201eJP Abgrallunsigned base_addr = 0x10000000; 817b8970c577c788c9af582dac797c63b3134b201eJP Abgrallunsigned kernel_offset = 0x00008000; 827b8970c577c788c9af582dac797c63b3134b201eJP Abgrallunsigned ramdisk_offset = 0x01000000; 837b8970c577c788c9af582dac797c63b3134b201eJP Abgrallunsigned second_offset = 0x00f00000; 847b8970c577c788c9af582dac797c63b3134b201eJP Abgrallunsigned tags_offset = 0x00000100; 857b8970c577c788c9af582dac797c63b3134b201eJP Abgrall 86622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandenum fb_buffer_type { 87622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand FB_BUFFER, 88622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand FB_BUFFER_SPARSE, 89622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand}; 90622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 91622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstruct fastboot_buffer { 92622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand enum fb_buffer_type type; 93622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand void *data; 948d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned int sz; 95622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand}; 96622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 97622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstatic struct { 98622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand char img_name[13]; 99622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand char sig_name[13]; 100622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand char part_name[9]; 101622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand bool is_optional; 10273a4ad288ffdabfbdac0930737def7fdcf65d07cDaniel Rosenberg} images[4] = { 103622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand {"boot.img", "boot.sig", "boot", false}, 104622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand {"recovery.img", "recovery.sig", "recovery", true}, 105622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand {"system.img", "system.sig", "system", false}, 10673a4ad288ffdabfbdac0930737def7fdcf65d07cDaniel Rosenberg {"tos.img", "tos.sig", "tos", true}, 107622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand}; 1082a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid get_my_path(char *path); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *find_item(const char *item, const char *product) 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *dir; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fn; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char path[PATH_MAX + 128]; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(item,"boot")) { 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fn = "boot.img"; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(item,"recovery")) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fn = "recovery.img"; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(item,"system")) { 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fn = "system.img"; 12373a4ad288ffdabfbdac0930737def7fdcf65d07cDaniel Rosenberg } else if(!strcmp(item,"tos")) { 12473a4ad288ffdabfbdac0930737def7fdcf65d07cDaniel Rosenberg fn = "tos.img"; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(item,"userdata")) { 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fn = "userdata.img"; 127d7608a40d6bed0d8ca686414a5a4f44b6d4d0435Jean-Baptiste Queru } else if(!strcmp(item,"cache")) { 128d7608a40d6bed0d8ca686414a5a4f44b6d4d0435Jean-Baptiste Queru fn = "cache.img"; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(item,"info")) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fn = "android-info.txt"; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"unknown partition '%s'\n", item); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(product) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project get_my_path(path); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(path + strlen(path), 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "../../../target/product/%s/%s", product, fn); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return strdup(path); 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 142ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dir = getenv("ANDROID_PRODUCT_OUT"); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((dir == 0) || (dir[0] == 0)) { 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 148ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(path, "%s/%s", dir, fn); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return strdup(path); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1538d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiystatic int64_t file_size(int fd) 154f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross{ 155622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct stat st; 156622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int ret; 157f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 158622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand ret = fstat(fd, &st); 159f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 160622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return ret ? -1 : st.st_size; 161f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 162f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 1638d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiystatic void *load_fd(int fd, unsigned *_sz) 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1658d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy char *data; 1668d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy int sz; 16764ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel int errno_tmp; 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1698d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy data = 0; 1708d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy 1718d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy sz = file_size(fd); 172622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (sz < 0) { 173622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand goto oops; 174622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = (char*) malloc(sz); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(data == 0) goto oops; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read(fd, data, sz) != sz) goto oops; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(_sz) *_sz = sz; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return data; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 18664ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel errno_tmp = errno; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(data != 0) free(data); 18964ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel errno = errno_tmp; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1938d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiystatic void *load_file(const char *fn, unsigned *_sz) 194622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand{ 195622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int fd; 196622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 197622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fd = open(fn, O_RDONLY | O_BINARY); 198622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if(fd < 0) return 0; 199622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 200622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return load_fd(fd, _sz); 201622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand} 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 203a032dedefe275b1d5a08b9856dfcfcb12579b4a7JP Abgrallint match_fastboot_with_serial(usb_ifc_info *info, const char *local_serial) 204a032dedefe275b1d5a08b9856dfcfcb12579b4a7JP Abgrall{ 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(vendor_id && (info->dev_vendor == vendor_id)) && 20609070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood (info->dev_vendor != 0x18d1) && // Google 207f60e8638282d66c108f1e1dea030856312f65892Wu, Hao (info->dev_vendor != 0x8087) && // Intel 208f614d64d4b4dfcd20c77ac3ccf2d9c9090a49303The Android Open Source Project (info->dev_vendor != 0x0451) && 209e25ff1c682ae5cc87af5e76de7e31a2702b620f3Robert CH Chou (info->dev_vendor != 0x0502) && 210509f7399b8f246f506307b22039e63323ec09622Dima Zavin (info->dev_vendor != 0x0fce) && // Sony Ericsson 211509f7399b8f246f506307b22039e63323ec09622Dima Zavin (info->dev_vendor != 0x05c6) && // Qualcomm 21209070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood (info->dev_vendor != 0x22b8) && // Motorola 21337e9e904360d6a8757c958dacaab1343eacb7fa8Erik Gilling (info->dev_vendor != 0x0955) && // Nvidia 214af82f21df7b87af2b378a46c8f338ebdd9c66175Xavier Ducrohet (info->dev_vendor != 0x413c) && // DELL 215746f3243f6d30ab51a36dcfea76eac3ba29ac625Xavier Ducrohet (info->dev_vendor != 0x2314) && // INQ Mobile 21673c019b30a7c70c50d2a854982143d5eb8c74f8cRamanan Rajeswaran (info->dev_vendor != 0x0b05) && // Asus 21709070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood (info->dev_vendor != 0x0bb4)) // HTC 21809070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood return -1; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(info->ifc_class != 0xff) return -1; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(info->ifc_subclass != 0x42) return -1; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(info->ifc_protocol != 0x03) return -1; 22213081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson // require matching serial number or device path if requested 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // at the command line with the -s option. 224a032dedefe275b1d5a08b9856dfcfcb12579b4a7JP Abgrall if (local_serial && (strcmp(local_serial, info->serial_number) != 0 && 225a032dedefe275b1d5a08b9856dfcfcb12579b4a7JP Abgrall strcmp(local_serial, info->device_path) != 0)) return -1; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2297b8970c577c788c9af582dac797c63b3134b201eJP Abgrallint match_fastboot(usb_ifc_info *info) 2307b8970c577c788c9af582dac797c63b3134b201eJP Abgrall{ 2317b8970c577c788c9af582dac797c63b3134b201eJP Abgrall return match_fastboot_with_serial(info, serial); 2327b8970c577c788c9af582dac797c63b3134b201eJP Abgrall} 2337b8970c577c788c9af582dac797c63b3134b201eJP Abgrall 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint list_devices_callback(usb_ifc_info *info) 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 236a032dedefe275b1d5a08b9856dfcfcb12579b4a7JP Abgrall if (match_fastboot_with_serial(info, NULL) == 0) { 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial = info->serial_number; 238b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes if (!info->writable) { 239b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes serial = "no permissions"; // like "adb devices" 240b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes } 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!serial[0]) { 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial = "????????????"; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 244866b1bd5051db4f22b634df1f8a06bc1c9aa2e26Scott Anderson // output compatible with "adb devices" 24513081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson if (!long_listing) { 24613081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson printf("%s\tfastboot\n", serial); 247866b1bd5051db4f22b634df1f8a06bc1c9aa2e26Scott Anderson } else if (!info->device_path) { 248866b1bd5051db4f22b634df1f8a06bc1c9aa2e26Scott Anderson printf("%-22s fastboot\n", serial); 24913081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson } else { 250866b1bd5051db4f22b634df1f8a06bc1c9aa2e26Scott Anderson printf("%-22s fastboot %s\n", serial, info->device_path); 25113081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson } 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle *open_device(void) 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static usb_handle *usb = 0; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int announce = 1; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(usb) return usb; 263ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb = usb_open(match_fastboot); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(usb) return usb; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(announce) { 268ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang announce = 0; 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"< waiting for device >\n"); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2715957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn usleep(1000); 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid list_devices(void) { 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // We don't actually open a USB device here, 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // just getting our callback called so we can 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // list all the connected devices. 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_open(list_devices_callback); 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usage(void) 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */ 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "usage: fastboot [ <option> ] <command>\n" 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "commands:\n" 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " update <filename> reflash device from update.zip\n" 2907e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " flashall flash boot, system, and if found,\n" 2917e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " recovery, tos\n" 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " flash <partition> [ <filename> ] write a file to a flash partition\n" 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " erase <partition> erase a flash partition\n" 2947e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n" 2957e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " Can override the fs type and/or\n" 2967e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " size the bootloader reports.\n" 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " getvar <variable> display a bootloader variable\n" 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " boot <kernel> [ <ramdisk> ] download and boot kernel\n" 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " flash:raw boot <kernel> [ <ramdisk> ] create bootimage and flash it\n" 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " devices list all connected devices\n" 30124ce4bc8d7c4706286ef0530870dea80a1a0cd11Bruce Beare " continue continue with autoboot\n" 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " reboot reboot device normally\n" 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " reboot-bootloader reboot device into bootloader\n" 304ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang " help show this help message\n" 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "options:\n" 3075ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall " -w erase userdata and cache (and format\n" 3085ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall " if supported by partition type)\n" 3095ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall " -u do not first erase partition before\n" 3105ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall " formatting\n" 31113081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson " -s <specific device> specify device serial number\n" 31213081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson " or path to device port\n" 31313081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson " -l with \"devices\", lists device paths\n" 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -p <product> specify product name\n" 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -c <cmdline> override kernel commandline\n" 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -i <vendor id> specify a custom USB vendor id\n" 3177e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " -b <base_addr> specify a custom kernel base address.\n" 3187e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " default: 0x10000000\n" 3197e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " -n <page size> specify the nand page size.\n" 3207e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " default: 2048\n" 3217e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " -S <size>[K|M|G] automatically sparse files greater\n" 3227e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall " than size. 0 to disable\n" 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3267b8970c577c788c9af582dac797c63b3134b201eJP Abgrallvoid *load_bootable_image(const char *kernel, const char *ramdisk, 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned *sz, const char *cmdline) 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *kdata = 0, *rdata = 0; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned ksize = 0, rsize = 0; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *bdata; 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned bsize; 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(kernel == 0) { 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "no image specified\n"); 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kdata = load_file(kernel, &ksize); 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(kdata == 0) { 34164ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel fprintf(stderr, "cannot load '%s': %s\n", kernel, strerror(errno)); 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 344ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* is this actually a boot image? */ 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline); 348ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ramdisk) { 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n"); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 353ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *sz = ksize; 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return kdata; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ramdisk) { 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rdata = load_file(ramdisk, &rsize); 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(rdata == 0) { 36164ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel fprintf(stderr,"cannot load '%s': %s\n", ramdisk, strerror(errno)); 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"creating boot image...\n"); 3677b8970c577c788c9af582dac797c63b3134b201eJP Abgrall bdata = mkbootimg(kdata, ksize, kernel_offset, 3687b8970c577c788c9af582dac797c63b3134b201eJP Abgrall rdata, rsize, ramdisk_offset, 3697b8970c577c788c9af582dac797c63b3134b201eJP Abgrall 0, 0, second_offset, 3707b8970c577c788c9af582dac797c63b3134b201eJP Abgrall page_size, base_addr, tags_offset, &bsize); 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(bdata == 0) { 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"failed to create boot.img\n"); 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"creating boot image - %d bytes\n", bsize); 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *sz = bsize; 378ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return bdata; 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3828d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiyvoid *unzip_file(zipfile_t zip, const char *name, unsigned *sz) 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *data; 3858d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy zipentry_t entry; 3868d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned datasz; 387ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 3888d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy entry = lookup_zipentry(zip, name); 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (entry == NULL) { 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "archive does not contain '%s'\n", name); 3918d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy return 0; 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3948d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy *sz = get_zipentry_size(entry); 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3968d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy datasz = *sz * 1.001; 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = malloc(datasz); 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3998d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if(data == 0) { 4008d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy fprintf(stderr, "failed to allocate %d bytes\n", *sz); 4018d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy return 0; 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (decompress_zipentry(entry, data, datasz)) { 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "failed to unzip '%s' from archive\n", name); 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(data); 4078d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy return 0; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 4098d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return data; 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 413622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstatic int unzip_to_file(zipfile_t zip, char *name) 414622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand{ 415622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int fd; 416622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand char *data; 4178d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned sz; 418622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 419622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fd = fileno(tmpfile()); 420622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (fd < 0) { 4218d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy return -1; 422622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 423622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 424622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand data = unzip_file(zip, name, &sz); 4258d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if (data == 0) { 426622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return -1; 427622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 428622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 4295957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn if (write(fd, data, sz) != (ssize_t)sz) { 430622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fd = -1; 431622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 432622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 433622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand free(data); 4348d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy lseek(fd, 0, SEEK_SET); 435622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return fd; 436622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand} 437622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *strip(char *s) 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(*s && isspace(*s)) s++; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = strlen(s); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(n-- > 0) { 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!isspace(s[n])) break; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s[n] = 0; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAX_OPTIONS 32 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int setup_requirement_line(char *name) 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *val[MAX_OPTIONS]; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char **out; 455b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville char *prod = NULL; 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n, count; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int invert = 0; 459ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(name, "reject ", 7)) { 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name += 7; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project invert = 1; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "require ", 8)) { 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name += 8; 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project invert = 0; 466b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } else if (!strncmp(name, "require-for-product:", 20)) { 467b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville // Get the product and point name past it 468b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville prod = name + 20; 469b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville name = strchr(name, ' '); 470b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (!name) return -1; 471b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville *name = 0; 472b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville name += 1; 473b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville invert = 0; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = strchr(name, '='); 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x == 0) return 0; 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = 0; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project val[0] = x + 1; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(count = 1; count < MAX_OPTIONS; count++) { 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = strchr(val[count - 1],'|'); 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x == 0) break; 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = 0; 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project val[count] = x + 1; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 487ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = strip(name); 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(n = 0; n < count; n++) val[n] = strip(val[n]); 490ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = strip(name); 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (name == 0) return -1; 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* work around an unfortunate name mismatch */ 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name,"board")) name = "product"; 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out = malloc(sizeof(char*) * count); 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (out == 0) return -1; 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(n = 0; n < count; n++) { 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out[n] = strdup(strip(val[n])); 50214e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes if (out[n] == 0) { 50314e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes for(size_t i = 0; i < n; ++i) { 50414e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes free((char*) out[i]); 50514e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes } 50614e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes free(out); 50714e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes return -1; 50814e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes } 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 511b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fb_queue_require(prod, name, invert, n, out); 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5158d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiystatic void setup_requirements(char *data, unsigned sz) 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 5178d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy char *s; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5198d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy s = data; 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (sz-- > 0) { 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(*s == '\n') { 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *s++ = 0; 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (setup_requirement_line(data)) { 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("out of memory"); 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = s; 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s++; 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid queue_info_dump(void) 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_notice("--------------------------------------------"); 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_display("version-bootloader", "Bootloader Version..."); 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_display("version-baseband", "Baseband Version....."); 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_display("serialno", "Serial Number........"); 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_notice("--------------------------------------------"); 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 542622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstatic struct sparse_file **load_sparse_files(int fd, int max_size) 543f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross{ 544f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross struct sparse_file *s; 545f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross int files; 546f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross struct sparse_file **out_s; 547f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 548f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross s = sparse_file_import_auto(fd, false); 549f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (!s) { 550622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("cannot sparse read file\n"); 551f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 552f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 553f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross files = sparse_file_resparse(s, max_size, NULL, 0); 554f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (files < 0) { 555622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("Failed to resparse\n"); 556f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 557f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 558f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross out_s = calloc(sizeof(struct sparse_file *), files + 1); 559f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (!out_s) { 560f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross die("Failed to allocate sparse file array\n"); 561f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 562f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 563f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross files = sparse_file_resparse(s, max_size, out_s, files); 564f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (files < 0) { 565622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("Failed to resparse\n"); 566f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 567f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 568f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return out_s; 569f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 570f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 571f838788e6a4d57634a53eb597ee76a597feffcb5Colin Crossstatic int64_t get_target_sparse_limit(struct usb_handle *usb) 572f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross{ 573f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross int64_t limit = 0; 574f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross char response[FB_RESPONSE_SZ + 1]; 575f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross int status = fb_getvar(usb, response, "max-download-size"); 576f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 577f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (!status) { 578f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross limit = strtoul(response, NULL, 0); 579f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (limit > 0) { 580cf86e2f85d98ed10cf5e0672e41631f6ea7e3e34Ying Wang fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", 581f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross limit); 582f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 583f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 584f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 585f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return limit; 586f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 587f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 588f838788e6a4d57634a53eb597ee76a597feffcb5Colin Crossstatic int64_t get_sparse_limit(struct usb_handle *usb, int64_t size) 589f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross{ 590f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross int64_t limit; 591f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 592f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (sparse_limit == 0) { 593f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return 0; 594f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else if (sparse_limit > 0) { 595f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross limit = sparse_limit; 596f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else { 597f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (target_sparse_limit == -1) { 598f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross target_sparse_limit = get_target_sparse_limit(usb); 599f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 600f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (target_sparse_limit > 0) { 601f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross limit = target_sparse_limit; 602f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else { 6030bbfb3976e9491b3e1a872ebdaa850ef868a24aaColin Cross return 0; 604f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 605f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 606f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 607f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (size > limit) { 608f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return limit; 609f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 610f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 611f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return 0; 612f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 613f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 6145ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall/* Until we get lazy inode table init working in make_ext4fs, we need to 6155ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall * erase partitions of type ext4 before flashing a filesystem so no stale 6165ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall * inodes are left lying around. Otherwise, e2fsck gets very upset. 6175ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall */ 6185ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrallstatic int needs_erase(const char *part) 6195ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall{ 6205ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall /* The function fb_format_supported() currently returns the value 6215ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall * we want, so just call it. 6225ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall */ 6237e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall return fb_format_supported(usb, part, NULL); 6245ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall} 6255ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall 626622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstatic int load_buf_fd(usb_handle *usb, int fd, 627622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct fastboot_buffer *buf) 628f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross{ 629782111b3bc5d372afc8d66ab6023e834b7c23b88Sasha Levitskiy int64_t sz64; 6308d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy void *data; 6318d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy int64_t limit; 632f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 6338d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy 6348d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy sz64 = file_size(fd); 6358d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if (sz64 < 0) { 6368d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy return -1; 637622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 638e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 639e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg lseek(fd, 0, SEEK_SET); 640f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross limit = get_sparse_limit(usb, sz64); 641f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (limit) { 642622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct sparse_file **s = load_sparse_files(fd, limit); 643f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (s == NULL) { 644622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return -1; 645f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 646622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand buf->type = FB_BUFFER_SPARSE; 647622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand buf->data = s; 648f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else { 6498d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned int sz; 650622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand data = load_fd(fd, &sz); 6518d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if (data == 0) return -1; 652622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand buf->type = FB_BUFFER; 653782111b3bc5d372afc8d66ab6023e834b7c23b88Sasha Levitskiy buf->data = data; 6548d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy buf->sz = sz; 655622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 656622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 657622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return 0; 658622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand} 659622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 660622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstatic int load_buf(usb_handle *usb, const char *fname, 661622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct fastboot_buffer *buf) 662622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand{ 663622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int fd; 664622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 665622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fd = open(fname, O_RDONLY | O_BINARY); 666622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (fd < 0) { 66782280594ef7e9dc908aa67f3da8661ff54a96c9eDaniel Rosenberg return -1; 668f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 669622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 670622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand return load_buf_fd(usb, fd, buf); 671622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand} 672622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 673622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandstatic void flash_buf(const char *pname, struct fastboot_buffer *buf) 674622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand{ 675622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct sparse_file **s; 676622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 677622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand switch (buf->type) { 678622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand case FB_BUFFER_SPARSE: 679622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand s = buf->data; 680622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand while (*s) { 681622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int64_t sz64 = sparse_file_len(*s, true, false); 682622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fb_queue_flash_sparse(pname, *s++, sz64); 683622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 684622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand break; 685622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand case FB_BUFFER: 686622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fb_queue_flash(pname, buf->data, buf->sz); 687622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand break; 688622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand default: 689622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("unknown buffer type: %d", buf->type); 690f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 691f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 692f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 693622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandvoid do_flash(usb_handle *usb, const char *pname, const char *fname) 694622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand{ 695622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct fastboot_buffer buf; 696622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand 697622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (load_buf(usb, fname, &buf)) { 698622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("cannot load '%s'", fname); 699622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 700622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand flash_buf(pname, &buf); 701f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 702f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid do_update_signature(zipfile_t zip, char *fn) 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 7058d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy void *data; 7068d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned sz; 7078d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy data = unzip_file(zip, fn, &sz); 7088d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if (data == 0) return; 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_download("signature", data, sz); 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_command("signature", "installing signature"); 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 713622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandvoid do_update(usb_handle *usb, char *fn, int erase_first) 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *zdata; 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned zsize; 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *data; 7188d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned sz; 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project zipfile_t zip; 720622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int fd; 721622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand int rc; 722622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct fastboot_buffer buf; 7235957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn size_t i; 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project queue_info_dump(); 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 727b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fb_queue_query_save("product", cur_product, sizeof(cur_product)); 728b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project zdata = load_file(fn, &zsize); 73064ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel if (zdata == 0) die("failed to load '%s': %s", fn, strerror(errno)); 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project zip = init_zipfile(zdata, zsize); 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(zip == 0) die("failed to access zipdata in '%s'"); 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = unzip_file(zip, "android-info.txt", &sz); 7368d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if (data == 0) { 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tmp; 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* fallback for older zipfiles */ 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = unzip_file(zip, "android-product.txt", &sz); 7408d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy if ((data == 0) || (sz < 1)) { 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("update package has no android-info.txt or android-product.txt"); 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp = malloc(sz + 128); 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tmp == 0) die("out of memory"); 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(tmp,"board=%sversion-baseband=0.66.04.19\n",(char*)data); 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = tmp; 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sz = strlen(tmp); 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setup_requirements(data, sz); 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 752622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand for (i = 0; i < ARRAY_SIZE(images); i++) { 753622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fd = unzip_to_file(zip, images[i].img_name); 754622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (fd < 0) { 755622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (images[i].is_optional) 756622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand continue; 757622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("update package missing %s", images[i].img_name); 7585ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 759622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand rc = load_buf_fd(usb, fd, &buf); 760622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (rc) die("cannot load %s from flash", images[i].img_name); 761622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand do_update_signature(zip, images[i].sig_name); 762622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (erase_first && needs_erase(images[i].part_name)) { 763622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fb_queue_erase(images[i].part_name); 764622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 765622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand flash_buf(images[i].part_name, &buf); 766622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand /* not closing the fd here since the sparse code keeps the fd around 767622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand * but hasn't mmaped data yet. The tmpfile will get cleaned up when the 768622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand * program exits. 769622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand */ 7705ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid do_send_signature(char *fn) 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *data; 7768d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned sz; 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *xtn; 778ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xtn = strrchr(fn, '.'); 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!xtn) return; 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strcmp(xtn, ".img")) return; 782ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(xtn,".sig"); 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = load_file(fn, &sz); 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(xtn,".img"); 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (data == 0) return; 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_download("signature", data, sz); 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_command("signature", "installing signature"); 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 791622810ceff6d98779171c68391465c7434adeb1dRom Lemarchandvoid do_flashall(usb_handle *usb, int erase_first) 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fname; 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *data; 7958d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned sz; 796622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand struct fastboot_buffer buf; 7975957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn size_t i; 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project queue_info_dump(); 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 801b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fb_queue_query_save("product", cur_product, sizeof(cur_product)); 802b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = find_item("info", product); 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fname == 0) die("cannot find android-info.txt"); 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = load_file(fname, &sz); 80664ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel if (data == 0) die("could not load android-info.txt: %s", strerror(errno)); 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setup_requirements(data, sz); 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 809622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand for (i = 0; i < ARRAY_SIZE(images); i++) { 810622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fname = find_item(images[i].part_name, product); 811622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (load_buf(usb, fname, &buf)) { 812622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (images[i].is_optional) 813622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand continue; 814622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand die("could not load %s\n", images[i].img_name); 815622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand } 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do_send_signature(fname); 817622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand if (erase_first && needs_erase(images[i].part_name)) { 818622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand fb_queue_erase(images[i].part_name); 8195ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 820622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand flash_buf(images[i].part_name, &buf); 8215ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define skip(n) do { argc -= (n); argv += (n); } while (0) 8252d13d1408bef9e26cc418e6fc2579dfd12378a3cJP Abgrall#define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0) 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint do_oem_command(int argc, char **argv) 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char command[256]; 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc <= 1) return 0; 831ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project command[0] = 0; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(1) { 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(command,*argv); 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc == 0) break; 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(command," "); 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 840ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang fb_queue_command(command,""); 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 844f838788e6a4d57634a53eb597ee76a597feffcb5Colin Crossstatic int64_t parse_num(const char *arg) 845f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross{ 846f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross char *endptr; 847f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross unsigned long long num; 848f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 849f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross num = strtoull(arg, &endptr, 0); 850f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (endptr == arg) { 851f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return -1; 852f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 853f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 854f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (*endptr == 'k' || *endptr == 'K') { 855f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (num >= (-1ULL) / 1024) { 856f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return -1; 857f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 858f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross num *= 1024LL; 859f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross endptr++; 860f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else if (*endptr == 'm' || *endptr == 'M') { 861f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (num >= (-1ULL) / (1024 * 1024)) { 862f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return -1; 863f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 864f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross num *= 1024LL * 1024LL; 865f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross endptr++; 866f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else if (*endptr == 'g' || *endptr == 'G') { 867f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (num >= (-1ULL) / (1024 * 1024 * 1024)) { 868f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return -1; 869f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 870f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross num *= 1024LL * 1024LL * 1024LL; 871f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross endptr++; 872f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 873f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 874f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (*endptr != '\0') { 875f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return -1; 876f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 877f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 878f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (num > INT64_MAX) { 879f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return -1; 880f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 881f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 882f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross return num; 883f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 884f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 8857e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrallvoid fb_perform_format(const char *partition, int skip_if_not_supported, 8867e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall const char *type_override, const char *size_override) 887e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg{ 8887e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1]; 8897e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall char *pType = pTypeBuff; 8907e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall char *pSize = pSizeBuff; 891e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg unsigned int limit = INT_MAX; 892e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg struct fastboot_buffer buf; 893e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg const char *errMsg = NULL; 894e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg const struct fs_generator *gen; 895e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg uint64_t pSz; 896e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg int status; 897e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg int fd; 898e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 899e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (target_sparse_limit > 0 && target_sparse_limit < limit) 900e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg limit = target_sparse_limit; 901e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (sparse_limit > 0 && sparse_limit < limit) 902e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg limit = sparse_limit; 903e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 904e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg status = fb_getvar(usb, pType, "partition-type:%s", partition); 905e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (status) { 906e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg errMsg = "Can't determine partition type.\n"; 907e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg goto failed; 908e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 9097e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (type_override) { 9107e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (strcmp(type_override, pType)) { 9117e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall fprintf(stderr, 9127e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall "Warning: %s type is %s, but %s was requested for formating.\n", 9137e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall partition, pType, type_override); 9147e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } 9155957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn pType = (char *)type_override; 9167e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } 917e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 918e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg status = fb_getvar(usb, pSize, "partition-size:%s", partition); 919e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (status) { 920e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg errMsg = "Unable to get partition size\n"; 921e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg goto failed; 922e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 9237e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (size_override) { 9247e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (strcmp(size_override, pSize)) { 9257e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall fprintf(stderr, 9267e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall "Warning: %s size is %s, but %s was requested for formating.\n", 9277e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall partition, pSize, size_override); 9287e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } 9295957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn pSize = (char *)size_override; 9307e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } 931e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 932e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg gen = fs_get_generator(pType); 933e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (!gen) { 934e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (skip_if_not_supported) { 935e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "Erase successful, but not automatically formatting.\n"); 936e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "File system type %s not supported.\n", pType); 937e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg return; 938e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 939e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType); 940e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg return; 941e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 942e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 943e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg pSz = strtoll(pSize, (char **)NULL, 16); 944e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 945e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fd = fileno(tmpfile()); 946e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (fs_generator_generate(gen, fd, pSz)) { 947e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg close(fd); 948e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "Cannot generate image.\n"); 949e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg return; 950e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 951e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 952e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (load_buf_fd(usb, fd, &buf)) { 953e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "Cannot read image.\n"); 954e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg close(fd); 955e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg return; 956e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 957e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg flash_buf(partition, &buf); 958e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 959e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg return; 960e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 961e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 962e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinbergfailed: 963e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (skip_if_not_supported) { 964e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "Erase successful, but not automatically formatting.\n"); 965e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg if (errMsg) 966e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr, "%s", errMsg); 967e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg } 968e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg fprintf(stderr,"FAILED (%s)\n", fb_get_error()); 969e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg} 970e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint main(int argc, char **argv) 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int wants_wipe = 0; 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int wants_reboot = 0; 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int wants_reboot_bootloader = 0; 9765ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall int erase_first = 1; 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *data; 9788d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiy unsigned sz; 979eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom int status; 9808879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross int c; 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9827b8970c577c788c9af582dac797c63b3134b201eJP Abgrall const struct option longopts[] = { 9837b8970c577c788c9af582dac797c63b3134b201eJP Abgrall {"base", required_argument, 0, 'b'}, 9847b8970c577c788c9af582dac797c63b3134b201eJP Abgrall {"kernel_offset", required_argument, 0, 'k'}, 9857b8970c577c788c9af582dac797c63b3134b201eJP Abgrall {"page_size", required_argument, 0, 'n'}, 9867b8970c577c788c9af582dac797c63b3134b201eJP Abgrall {"ramdisk_offset", required_argument, 0, 'r'}, 98729fd7b1f4f86e4955cf78156a9de174c5b7233c1Mohamad Ayyash {"tags_offset", required_argument, 0, 't'}, 9887b8970c577c788c9af582dac797c63b3134b201eJP Abgrall {"help", 0, 0, 'h'}, 9897b8970c577c788c9af582dac797c63b3134b201eJP Abgrall {0, 0, 0, 0} 9907b8970c577c788c9af582dac797c63b3134b201eJP Abgrall }; 9918879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross 9928879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross serial = getenv("ANDROID_SERIAL"); 9938879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross 9948879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross while (1) { 99529fd7b1f4f86e4955cf78156a9de174c5b7233c1Mohamad Ayyash c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, NULL); 9968879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross if (c < 0) { 9978879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross break; 9988879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross } 9997b8970c577c788c9af582dac797c63b3134b201eJP Abgrall /* Alphabetical cases */ 10008879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross switch (c) { 10018879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross case 'b': 10028879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross base_addr = strtoul(optarg, 0, 16); 10038879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross break; 10047b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'c': 10057b8970c577c788c9af582dac797c63b3134b201eJP Abgrall cmdline = optarg; 10067b8970c577c788c9af582dac797c63b3134b201eJP Abgrall break; 10077b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'h': 10087b8970c577c788c9af582dac797c63b3134b201eJP Abgrall usage(); 10097b8970c577c788c9af582dac797c63b3134b201eJP Abgrall return 1; 10107b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'i': { 10117b8970c577c788c9af582dac797c63b3134b201eJP Abgrall char *endptr = NULL; 10127b8970c577c788c9af582dac797c63b3134b201eJP Abgrall unsigned long val; 10137b8970c577c788c9af582dac797c63b3134b201eJP Abgrall 10147b8970c577c788c9af582dac797c63b3134b201eJP Abgrall val = strtoul(optarg, &endptr, 0); 10157b8970c577c788c9af582dac797c63b3134b201eJP Abgrall if (!endptr || *endptr != '\0' || (val & ~0xffff)) 10167b8970c577c788c9af582dac797c63b3134b201eJP Abgrall die("invalid vendor id '%s'", optarg); 10177b8970c577c788c9af582dac797c63b3134b201eJP Abgrall vendor_id = (unsigned short)val; 10187b8970c577c788c9af582dac797c63b3134b201eJP Abgrall break; 10197b8970c577c788c9af582dac797c63b3134b201eJP Abgrall } 10207b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'k': 10217b8970c577c788c9af582dac797c63b3134b201eJP Abgrall kernel_offset = strtoul(optarg, 0, 16); 10227b8970c577c788c9af582dac797c63b3134b201eJP Abgrall break; 10237b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'l': 10247b8970c577c788c9af582dac797c63b3134b201eJP Abgrall long_listing = 1; 10257b8970c577c788c9af582dac797c63b3134b201eJP Abgrall break; 10268879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross case 'n': 10278879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross page_size = (unsigned)strtoul(optarg, NULL, 0); 10288879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross if (!page_size) die("invalid page size"); 10298879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross break; 10307b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'p': 10317b8970c577c788c9af582dac797c63b3134b201eJP Abgrall product = optarg; 10327b8970c577c788c9af582dac797c63b3134b201eJP Abgrall break; 10337b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'r': 10347b8970c577c788c9af582dac797c63b3134b201eJP Abgrall ramdisk_offset = strtoul(optarg, 0, 16); 10357b8970c577c788c9af582dac797c63b3134b201eJP Abgrall break; 103629fd7b1f4f86e4955cf78156a9de174c5b7233c1Mohamad Ayyash case 't': 103729fd7b1f4f86e4955cf78156a9de174c5b7233c1Mohamad Ayyash tags_offset = strtoul(optarg, 0, 16); 103829fd7b1f4f86e4955cf78156a9de174c5b7233c1Mohamad Ayyash break; 10398879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross case 's': 10408879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross serial = optarg; 10418879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross break; 1042f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross case 'S': 1043f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross sparse_limit = parse_num(optarg); 1044f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (sparse_limit < 0) { 1045f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross die("invalid sparse limit"); 1046f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } 1047f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross break; 10487b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'u': 10497b8970c577c788c9af582dac797c63b3134b201eJP Abgrall erase_first = 0; 10508879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross break; 10517b8970c577c788c9af582dac797c63b3134b201eJP Abgrall case 'w': 10527b8970c577c788c9af582dac797c63b3134b201eJP Abgrall wants_wipe = 1; 10538879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross break; 10548879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross case '?': 10558879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross return 1; 10568879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross default: 10578879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross abort(); 10588879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross } 10598879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross } 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10618879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross argc -= optind; 10628879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross argv += optind; 10638879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross 10648879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross if (argc == 0 && !wants_wipe) { 1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usage(); 1066eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom return 1; 1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10698fb6e06ba44b92258bf44110ea5361496257e24eColin Cross if (argc > 0 && !strcmp(*argv, "devices")) { 10708879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross skip(1); 1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project list_devices(); 1072ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang return 0; 1073ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang } 1074ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 1075c7b75dcc1aa121574d7677c97ff7d9b4ba91e624Colin Cross if (argc > 0 && !strcmp(*argv, "help")) { 1076c7b75dcc1aa121574d7677c97ff7d9b4ba91e624Colin Cross usage(); 1077c7b75dcc1aa121574d7677c97ff7d9b4ba91e624Colin Cross return 0; 1078c7b75dcc1aa121574d7677c97ff7d9b4ba91e624Colin Cross } 1079c7b75dcc1aa121574d7677c97ff7d9b4ba91e624Colin Cross 10808879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross usb = open_device(); 108131dbed7b60d8237d6d05dc6bf230167a5854b77aElliott Hughes 1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (argc > 0) { 10838879f988bac8d4cb46fb82e3d82ad69a9ed89b16Colin Cross if(!strcmp(*argv, "getvar")) { 1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project require(2); 1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_display(argv[1], argv[1]); 1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(2); 1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "erase")) { 1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project require(2); 10895ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall 10907e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (fb_format_supported(usb, argv[1], NULL)) { 10915ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); 10925ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 10935ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall 1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_erase(argv[1]); 1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(2); 10967e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } else if(!strncmp(*argv, "format", strlen("format"))) { 10977e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall char *overrides; 10987e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall char *type_override = NULL; 10997e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall char *size_override = NULL; 1100c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau require(2); 11017e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall /* 11027e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * Parsing for: "format[:[type][:[size]]]" 11037e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * Some valid things: 11047e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * - select ontly the size, and leave default fs type: 11057e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * format::0x4000000 userdata 11067e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * - default fs type and size: 11077e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * format userdata 11087e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall * format:: userdata 11097e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall */ 11107e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall overrides = strchr(*argv, ':'); 11117e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (overrides) { 11127e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall overrides++; 11137e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall size_override = strchr(overrides, ':'); 11147e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (size_override) { 11157e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall size_override[0] = '\0'; 11167e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall size_override++; 11177e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } 11187e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall type_override = overrides; 11197e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall } 11207e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (type_override && !type_override[0]) type_override = NULL; 11217e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall if (size_override && !size_override[0]) size_override = NULL; 11225ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall if (erase_first && needs_erase(argv[1])) { 11235ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall fb_queue_erase(argv[1]); 11245ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 11257e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall fb_perform_format(argv[1], 0, type_override, size_override); 1126c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau skip(2); 1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "signature")) { 1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project require(2); 1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = load_file(argv[1], &sz); 113064ba258b7a17fd5f0abd788c1b021ad45ad732b9Matt Gumbel if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno)); 1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sz != 256) die("signature must be 256 bytes"); 1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_download("signature", data, sz); 1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_command("signature", "installing signature"); 1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(2); 1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "reboot")) { 1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wants_reboot = 1; 1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "reboot-bootloader")) { 1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wants_reboot_bootloader = 1; 1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(*argv, "continue")) { 1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_command("continue", "resuming boot"); 1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "boot")) { 1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *kname = 0; 1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *rname = 0; 1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc > 0) { 1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kname = argv[0]; 1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc > 0) { 1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rname = argv[0]; 1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 11567b8970c577c788c9af582dac797c63b3134b201eJP Abgrall data = load_bootable_image(kname, rname, &sz, cmdline); 1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (data == 0) return 1; 1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_download("boot.img", data, sz); 1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_command("boot", "booting"); 1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "flash")) { 1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *pname = argv[1]; 1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fname = 0; 1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project require(2); 1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc > 2) { 1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = argv[2]; 1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(3); 1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = find_item(pname, product); 1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(2); 1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fname == 0) die("cannot determine image filename for '%s'", pname); 11725ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall if (erase_first && needs_erase(pname)) { 11735ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall fb_queue_erase(pname); 11745ee5d389d6cb90b3cd2856730f8ff12211bc95d2Ken Sumrall } 1175f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross do_flash(usb, pname, fname); 1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "flash:raw")) { 1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *pname = argv[1]; 1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *kname = argv[2]; 1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *rname = 0; 1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project require(3); 1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc > 3) { 1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rname = argv[3]; 1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(4); 1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(3); 1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 11877b8970c577c788c9af582dac797c63b3134b201eJP Abgrall data = load_bootable_image(kname, rname, &sz, cmdline); 1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (data == 0) die("cannot load bootable image"); 1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_flash(pname, data, sz); 1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "flashall")) { 1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1192622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand do_flashall(usb, erase_first); 1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wants_reboot = 1; 1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "update")) { 1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc > 1) { 1196622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand do_update(usb, argv[1], erase_first); 1197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(2); 1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1199622810ceff6d98779171c68391465c7434adeb1dRom Lemarchand do_update(usb, "update.zip", erase_first); 1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project skip(1); 1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wants_reboot = 1; 1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(*argv, "oem")) { 1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc = do_oem_command(argc, argv); 1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usage(); 1207ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang return 1; 1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (wants_wipe) { 1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_erase("userdata"); 12137e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall fb_perform_format("userdata", 1, NULL, NULL); 1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_erase("cache"); 12157e85974fc2fc48a0cea7bb9bafcfcda863138eb6JP Abgrall fb_perform_format("cache", 1, NULL, NULL); 1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (wants_reboot) { 1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_reboot(); 1219ec25e7bc4bb8c203f89f133136a62a08410d6cebMark Wachsler fb_queue_wait_for_disconnect(); 1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (wants_reboot_bootloader) { 1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb_queue_command("reboot-bootloader", "rebooting into bootloader"); 1222157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler fb_queue_wait_for_disconnect(); 1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 122513081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson if (fb_queue_is_empty()) 122613081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson return 0; 122713081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson 1228eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom status = fb_execute_queue(usb); 1229eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom return (status) ? 1 : 0; 1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1231