├── Android.mk ├── README.md ├── bootimg_utils.cpp ├── bootimg_utils.h ├── engine.c ├── engineering_key.p12 ├── fastboot.cpp ├── fastboot.h ├── fastboot_protocol.txt ├── fs.c ├── fs.h ├── genkey.sh ├── p12topem.sh ├── protocol.c ├── signfile.sh ├── usb.h ├── usb_linux.c ├── usb_osx.c ├── usb_windows.c ├── usbtest.c ├── util.c ├── util_linux.c ├── util_osx.c └── util_windows.c /Android.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | LOCAL_PATH:= $(call my-dir) 16 | 17 | fastboot_version := $(shell git -C $(LOCAL_PATH) rev-parse --short=12 HEAD 2>/dev/null)-android 18 | 19 | include $(CLEAR_VARS) 20 | 21 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \ 22 | $(LOCAL_PATH)/../../extras/ext4_utils \ 23 | $(LOCAL_PATH)/../../extras/f2fs_utils 24 | LOCAL_SRC_FILES := protocol.c engine.c bootimg_utils.cpp fastboot.cpp util.c fs.c 25 | LOCAL_MODULE := fastboot 26 | LOCAL_MODULE_TAGS := debug 27 | LOCAL_CONLYFLAGS += -std=gnu99 28 | LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code 29 | 30 | LOCAL_CFLAGS += -DFASTBOOT_REVISION='"$(fastboot_version)"' 31 | 32 | ifeq ($(HOST_OS),linux) 33 | LOCAL_SRC_FILES += usb_linux.c util_linux.c 34 | endif 35 | 36 | ifeq ($(HOST_OS),darwin) 37 | LOCAL_SRC_FILES += usb_osx.c util_osx.c 38 | LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon 39 | LOCAL_CFLAGS += -Wno-unused-parameter 40 | endif 41 | 42 | ifeq ($(HOST_OS),windows) 43 | LOCAL_SRC_FILES += usb_windows.c util_windows.c 44 | EXTRA_STATIC_LIBS := AdbWinApi 45 | ifneq ($(strip $(USE_CYGWIN)),) 46 | # Pure cygwin case 47 | LOCAL_LDLIBS += -lpthread 48 | endif 49 | ifneq ($(strip $(USE_MINGW)),) 50 | # MinGW under Linux case 51 | LOCAL_LDLIBS += -lws2_32 52 | USE_SYSDEPS_WIN32 := 1 53 | endif 54 | LOCAL_C_INCLUDES += development/host/windows/usb/api 55 | endif 56 | 57 | LOCAL_STATIC_LIBRARIES := \ 58 | $(EXTRA_STATIC_LIBS) \ 59 | libziparchive-host \ 60 | libext4_utils_host \ 61 | libsparse_host \ 62 | libutils \ 63 | liblog \ 64 | libz \ 65 | libbase 66 | 67 | ifneq ($(HOST_OS),windows) 68 | LOCAL_STATIC_LIBRARIES += libselinux 69 | endif # HOST_OS != windows 70 | 71 | ifeq ($(HOST_OS),linux) 72 | # libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn") 73 | LOCAL_CFLAGS += -DUSE_F2FS 74 | LOCAL_LDFLAGS += -ldl -rdynamic -Wl,-rpath,. 75 | LOCAL_REQUIRED_MODULES := libf2fs_fmt_host_dyn 76 | # The following libf2fs_* are from system/extras/f2fs_utils, 77 | # and do not use code in external/f2fs-tools. 78 | LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host 79 | endif 80 | 81 | # libc++ not available on windows yet 82 | ifneq ($(HOST_OS),windows) 83 | LOCAL_CXX_STL := libc++_static 84 | endif 85 | 86 | # Don't add anything here, we don't want additional shared dependencies 87 | # on the host fastboot tool, and shared libraries that link against libc++ 88 | # will violate ODR 89 | LOCAL_SHARED_LIBRARIES := 90 | 91 | include $(BUILD_HOST_EXECUTABLE) 92 | 93 | my_dist_files := $(LOCAL_BUILT_MODULE) 94 | ifeq ($(HOST_OS),linux) 95 | my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX) 96 | endif 97 | $(call dist-for-goals,dist_files sdk,$(my_dist_files)) 98 | my_dist_files := 99 | 100 | 101 | ifeq ($(HOST_OS),linux) 102 | include $(CLEAR_VARS) 103 | LOCAL_SRC_FILES := usbtest.c usb_linux.c util.c 104 | LOCAL_MODULE := usbtest 105 | LOCAL_CFLAGS := -Werror 106 | include $(BUILD_HOST_EXECUTABLE) 107 | endif 108 | 109 | ifeq ($(HOST_OS),windows) 110 | $(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll 111 | endif 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fastboot 2 | unlock or lock bootloader for vivo(bbk) devices 3 | 步步高手机解锁bootloader专用fastboot 4 | 解锁命令fastboot bbk unlock_vivo 5 | 上锁命令fastboot bbk lock_vivo 6 | -------------------------------------------------------------------------------- /bootimg_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include "bootimg_utils.h" 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline) 36 | { 37 | strcpy((char*) h->cmdline, cmdline); 38 | } 39 | 40 | boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset, 41 | void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset, 42 | void *second, unsigned second_size, unsigned second_offset, 43 | unsigned page_size, unsigned base, unsigned tags_offset, 44 | unsigned *bootimg_size) 45 | { 46 | unsigned kernel_actual; 47 | unsigned ramdisk_actual; 48 | unsigned second_actual; 49 | unsigned page_mask; 50 | 51 | page_mask = page_size - 1; 52 | 53 | kernel_actual = (kernel_size + page_mask) & (~page_mask); 54 | ramdisk_actual = (ramdisk_size + page_mask) & (~page_mask); 55 | second_actual = (second_size + page_mask) & (~page_mask); 56 | 57 | *bootimg_size = page_size + kernel_actual + ramdisk_actual + second_actual; 58 | 59 | boot_img_hdr* hdr = reinterpret_cast(calloc(*bootimg_size, 1)); 60 | if (hdr == 0) { 61 | return hdr; 62 | } 63 | 64 | memcpy(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); 65 | 66 | hdr->kernel_size = kernel_size; 67 | hdr->ramdisk_size = ramdisk_size; 68 | hdr->second_size = second_size; 69 | 70 | hdr->kernel_addr = base + kernel_offset; 71 | hdr->ramdisk_addr = base + ramdisk_offset; 72 | hdr->second_addr = base + second_offset; 73 | hdr->tags_addr = base + tags_offset; 74 | 75 | hdr->page_size = page_size; 76 | 77 | 78 | memcpy(hdr->magic + page_size, 79 | kernel, kernel_size); 80 | memcpy(hdr->magic + page_size + kernel_actual, 81 | ramdisk, ramdisk_size); 82 | memcpy(hdr->magic + page_size + kernel_actual + ramdisk_actual, 83 | second, second_size); 84 | return hdr; 85 | } 86 | -------------------------------------------------------------------------------- /bootimg_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _FASTBOOT_BOOTIMG_UTILS_H_ 30 | #define _FASTBOOT_BOOTIMG_UTILS_H_ 31 | 32 | #include 33 | 34 | #if defined(__cplusplus) 35 | extern "C" { 36 | #endif 37 | 38 | void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline); 39 | boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset, 40 | void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset, 41 | void *second, unsigned second_size, unsigned second_offset, 42 | unsigned page_size, unsigned base, unsigned tags_offset, 43 | unsigned *bootimg_size); 44 | 45 | #if defined(__cplusplus) 46 | } 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /engine.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include "fastboot.h" 30 | #include "fs.h" 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #ifdef USE_MINGW 43 | #include 44 | #else 45 | #include 46 | #endif 47 | 48 | #ifndef __unused 49 | #define __unused __attribute__((__unused__)) 50 | #endif 51 | 52 | #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 53 | 54 | #define OP_DOWNLOAD 1 55 | #define OP_COMMAND 2 56 | #define OP_QUERY 3 57 | #define OP_NOTICE 4 58 | #define OP_DOWNLOAD_SPARSE 5 59 | #define OP_WAIT_FOR_DISCONNECT 6 60 | 61 | typedef struct Action Action; 62 | 63 | #define CMD_SIZE 64 64 | 65 | struct Action 66 | { 67 | unsigned op; 68 | Action *next; 69 | 70 | char cmd[CMD_SIZE]; 71 | const char *prod; 72 | void *data; 73 | unsigned size; 74 | 75 | const char *msg; 76 | int (*func)(Action *a, int status, char *resp); 77 | 78 | double start; 79 | }; 80 | 81 | static Action *action_list = 0; 82 | static Action *action_last = 0; 83 | 84 | 85 | 86 | 87 | int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...) 88 | { 89 | char cmd[CMD_SIZE] = "getvar:"; 90 | int getvar_len = strlen(cmd); 91 | va_list args; 92 | 93 | response[FB_RESPONSE_SZ] = '\0'; 94 | va_start(args, fmt); 95 | vsnprintf(cmd + getvar_len, sizeof(cmd) - getvar_len, fmt, args); 96 | va_end(args); 97 | cmd[CMD_SIZE - 1] = '\0'; 98 | return fb_command_response(usb, cmd, response); 99 | } 100 | 101 | 102 | /* Return true if this partition is supported by the fastboot format command. 103 | * It is also used to determine if we should first erase a partition before 104 | * flashing it with an ext4 filesystem. See needs_erase() 105 | * 106 | * Not all devices report the filesystem type, so don't report any errors, 107 | * just return false. 108 | */ 109 | int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) 110 | { 111 | char fs_type[FB_RESPONSE_SZ + 1] = {0,}; 112 | int status; 113 | 114 | if (type_override) { 115 | return !!fs_get_generator(type_override); 116 | } 117 | status = fb_getvar(usb, fs_type, "partition-type:%s", partition); 118 | if (status) { 119 | return 0; 120 | } 121 | return !!fs_get_generator(fs_type); 122 | } 123 | 124 | static int cb_default(Action *a, int status, char *resp) 125 | { 126 | if (status) { 127 | fprintf(stderr,"FAILED (%s)\n", resp); 128 | } else { 129 | double split = now(); 130 | fprintf(stderr,"OKAY [%7.3fs]\n", (split - a->start)); 131 | a->start = split; 132 | } 133 | return status; 134 | } 135 | 136 | static Action *queue_action(unsigned op, const char *fmt, ...) 137 | { 138 | Action *a; 139 | va_list ap; 140 | size_t cmdsize; 141 | 142 | a = calloc(1, sizeof(Action)); 143 | if (a == 0) die("out of memory"); 144 | 145 | va_start(ap, fmt); 146 | cmdsize = vsnprintf(a->cmd, sizeof(a->cmd), fmt, ap); 147 | va_end(ap); 148 | 149 | if (cmdsize >= sizeof(a->cmd)) { 150 | free(a); 151 | die("Command length (%d) exceeds maximum size (%d)", cmdsize, sizeof(a->cmd)); 152 | } 153 | 154 | if (action_last) { 155 | action_last->next = a; 156 | } else { 157 | action_list = a; 158 | } 159 | action_last = a; 160 | a->op = op; 161 | a->func = cb_default; 162 | 163 | a->start = -1; 164 | 165 | return a; 166 | } 167 | 168 | void fb_queue_erase(const char *ptn) 169 | { 170 | Action *a; 171 | a = queue_action(OP_COMMAND, "erase:%s", ptn); 172 | a->msg = mkmsg("erasing '%s'", ptn); 173 | } 174 | 175 | void fb_queue_flash(const char *ptn, void *data, unsigned sz) 176 | { 177 | Action *a; 178 | 179 | a = queue_action(OP_DOWNLOAD, ""); 180 | a->data = data; 181 | a->size = sz; 182 | a->msg = mkmsg("sending '%s' (%d KB)", ptn, sz / 1024); 183 | 184 | a = queue_action(OP_COMMAND, "flash:%s", ptn); 185 | a->msg = mkmsg("writing '%s'", ptn); 186 | } 187 | 188 | void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, unsigned sz) 189 | { 190 | Action *a; 191 | 192 | a = queue_action(OP_DOWNLOAD_SPARSE, ""); 193 | a->data = s; 194 | a->size = 0; 195 | a->msg = mkmsg("sending sparse '%s' (%d KB)", ptn, sz / 1024); 196 | 197 | a = queue_action(OP_COMMAND, "flash:%s", ptn); 198 | a->msg = mkmsg("writing '%s'", ptn); 199 | } 200 | 201 | static int match(char *str, const char **value, unsigned count) 202 | { 203 | unsigned n; 204 | 205 | for (n = 0; n < count; n++) { 206 | const char *val = value[n]; 207 | int len = strlen(val); 208 | int match; 209 | 210 | if ((len > 1) && (val[len-1] == '*')) { 211 | len--; 212 | match = !strncmp(val, str, len); 213 | } else { 214 | match = !strcmp(val, str); 215 | } 216 | 217 | if (match) return 1; 218 | } 219 | 220 | return 0; 221 | } 222 | 223 | 224 | 225 | static int cb_check(Action *a, int status, char *resp, int invert) 226 | { 227 | const char **value = a->data; 228 | unsigned count = a->size; 229 | unsigned n; 230 | int yes; 231 | 232 | if (status) { 233 | fprintf(stderr,"FAILED (%s)\n", resp); 234 | return status; 235 | } 236 | 237 | if (a->prod) { 238 | if (strcmp(a->prod, cur_product) != 0) { 239 | double split = now(); 240 | fprintf(stderr,"IGNORE, product is %s required only for %s [%7.3fs]\n", 241 | cur_product, a->prod, (split - a->start)); 242 | a->start = split; 243 | return 0; 244 | } 245 | } 246 | 247 | yes = match(resp, value, count); 248 | if (invert) yes = !yes; 249 | 250 | if (yes) { 251 | double split = now(); 252 | fprintf(stderr,"OKAY [%7.3fs]\n", (split - a->start)); 253 | a->start = split; 254 | return 0; 255 | } 256 | 257 | fprintf(stderr,"FAILED\n\n"); 258 | fprintf(stderr,"Device %s is '%s'.\n", a->cmd + 7, resp); 259 | fprintf(stderr,"Update %s '%s'", 260 | invert ? "rejects" : "requires", value[0]); 261 | for (n = 1; n < count; n++) { 262 | fprintf(stderr," or '%s'", value[n]); 263 | } 264 | fprintf(stderr,".\n\n"); 265 | return -1; 266 | } 267 | 268 | static int cb_require(Action *a, int status, char *resp) 269 | { 270 | return cb_check(a, status, resp, 0); 271 | } 272 | 273 | static int cb_reject(Action *a, int status, char *resp) 274 | { 275 | return cb_check(a, status, resp, 1); 276 | } 277 | 278 | void fb_queue_require(const char *prod, const char *var, 279 | int invert, unsigned nvalues, const char **value) 280 | { 281 | Action *a; 282 | a = queue_action(OP_QUERY, "getvar:%s", var); 283 | a->prod = prod; 284 | a->data = value; 285 | a->size = nvalues; 286 | a->msg = mkmsg("checking %s", var); 287 | a->func = invert ? cb_reject : cb_require; 288 | if (a->data == 0) die("out of memory"); 289 | } 290 | 291 | static int cb_display(Action *a, int status, char *resp) 292 | { 293 | if (status) { 294 | fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); 295 | return status; 296 | } 297 | fprintf(stderr, "%s: %s\n", (char*) a->data, resp); 298 | return 0; 299 | } 300 | 301 | void fb_queue_display(const char *var, const char *prettyname) 302 | { 303 | Action *a; 304 | a = queue_action(OP_QUERY, "getvar:%s", var); 305 | a->data = strdup(prettyname); 306 | if (a->data == 0) die("out of memory"); 307 | a->func = cb_display; 308 | } 309 | 310 | static int cb_save(Action *a, int status, char *resp) 311 | { 312 | if (status) { 313 | fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); 314 | return status; 315 | } 316 | strncpy(a->data, resp, a->size); 317 | return 0; 318 | } 319 | 320 | void fb_queue_query_save(const char *var, char *dest, unsigned dest_size) 321 | { 322 | Action *a; 323 | a = queue_action(OP_QUERY, "getvar:%s", var); 324 | a->data = (void *)dest; 325 | a->size = dest_size; 326 | a->func = cb_save; 327 | } 328 | 329 | static int cb_do_nothing(Action *a __unused, int status __unused, char *resp __unused) 330 | { 331 | fprintf(stderr,"\n"); 332 | return 0; 333 | } 334 | 335 | void fb_queue_reboot(void) 336 | { 337 | Action *a = queue_action(OP_COMMAND, "reboot"); 338 | a->func = cb_do_nothing; 339 | a->msg = "rebooting"; 340 | } 341 | 342 | void fb_queue_command(const char *cmd, const char *msg) 343 | { 344 | Action *a = queue_action(OP_COMMAND, cmd); 345 | a->msg = msg; 346 | } 347 | 348 | void fb_queue_download(const char *name, void *data, unsigned size) 349 | { 350 | Action *a = queue_action(OP_DOWNLOAD, ""); 351 | a->data = data; 352 | a->size = size; 353 | a->msg = mkmsg("downloading '%s'", name); 354 | } 355 | 356 | void fb_queue_notice(const char *notice) 357 | { 358 | Action *a = queue_action(OP_NOTICE, ""); 359 | a->data = (void*) notice; 360 | } 361 | 362 | void fb_queue_wait_for_disconnect(void) 363 | { 364 | queue_action(OP_WAIT_FOR_DISCONNECT, ""); 365 | } 366 | 367 | int fb_execute_queue(usb_handle *usb) 368 | { 369 | Action *a; 370 | char resp[FB_RESPONSE_SZ+1]; 371 | int status = 0; 372 | 373 | a = action_list; 374 | if (!a) 375 | return status; 376 | resp[FB_RESPONSE_SZ] = 0; 377 | 378 | double start = -1; 379 | for (a = action_list; a; a = a->next) { 380 | a->start = now(); 381 | if (start < 0) start = a->start; 382 | if (a->msg) { 383 | // fprintf(stderr,"%30s... ",a->msg); 384 | fprintf(stderr,"%s...\n",a->msg); 385 | } 386 | if (a->op == OP_DOWNLOAD) { 387 | status = fb_download_data(usb, a->data, a->size); 388 | status = a->func(a, status, status ? fb_get_error() : ""); 389 | if (status) break; 390 | } else if (a->op == OP_COMMAND) { 391 | status = fb_command(usb, a->cmd); 392 | status = a->func(a, status, status ? fb_get_error() : ""); 393 | if (status) break; 394 | } else if (a->op == OP_QUERY) { 395 | status = fb_command_response(usb, a->cmd, resp); 396 | status = a->func(a, status, status ? fb_get_error() : resp); 397 | if (status) break; 398 | } else if (a->op == OP_NOTICE) { 399 | fprintf(stderr,"%s\n",(char*)a->data); 400 | } else if (a->op == OP_DOWNLOAD_SPARSE) { 401 | status = fb_download_data_sparse(usb, a->data); 402 | status = a->func(a, status, status ? fb_get_error() : ""); 403 | if (status) break; 404 | } else if (a->op == OP_WAIT_FOR_DISCONNECT) { 405 | usb_wait_for_disconnect(usb); 406 | } else { 407 | die("bogus action"); 408 | } 409 | } 410 | 411 | fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); 412 | return status; 413 | } 414 | 415 | int fb_queue_is_empty(void) 416 | { 417 | return (action_list == NULL); 418 | } 419 | -------------------------------------------------------------------------------- /engineering_key.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppma/fastboot/a3e89583decaa637a91db3f70656d172809e4795/engineering_key.p12 -------------------------------------------------------------------------------- /fastboot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #define _LARGEFILE64_SOURCE 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | #include 49 | 50 | #include "bootimg_utils.h" 51 | #include "fastboot.h" 52 | #include "fs.h" 53 | 54 | #ifndef O_BINARY 55 | #define O_BINARY 0 56 | #endif 57 | 58 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) 59 | 60 | char cur_product[FB_RESPONSE_SZ + 1]; 61 | 62 | static const char *serial = 0; 63 | static const char *product = 0; 64 | static const char *cmdline = 0; 65 | static unsigned short vendor_id = 0; 66 | static int long_listing = 0; 67 | static int64_t sparse_limit = -1; 68 | static int64_t target_sparse_limit = -1; 69 | 70 | unsigned page_size = 2048; 71 | unsigned base_addr = 0x10000000; 72 | unsigned kernel_offset = 0x00008000; 73 | unsigned ramdisk_offset = 0x01000000; 74 | unsigned second_offset = 0x00f00000; 75 | unsigned tags_offset = 0x00000100; 76 | 77 | enum fb_buffer_type { 78 | FB_BUFFER, 79 | FB_BUFFER_SPARSE, 80 | }; 81 | 82 | struct fastboot_buffer { 83 | enum fb_buffer_type type; 84 | void *data; 85 | unsigned int sz; 86 | }; 87 | 88 | static struct { 89 | char img_name[13]; 90 | char sig_name[13]; 91 | char part_name[9]; 92 | bool is_optional; 93 | } images[] = { 94 | {"boot.img", "boot.sig", "boot", false}, 95 | {"recovery.img", "recovery.sig", "recovery", true}, 96 | {"system.img", "system.sig", "system", false}, 97 | {"vendor.img", "vendor.sig", "vendor", true}, 98 | }; 99 | 100 | char *find_item(const char *item, const char *product) 101 | { 102 | char *dir; 103 | const char *fn; 104 | char path[PATH_MAX + 128]; 105 | 106 | if(!strcmp(item,"boot")) { 107 | fn = "boot.img"; 108 | } else if(!strcmp(item,"recovery")) { 109 | fn = "recovery.img"; 110 | } else if(!strcmp(item,"system")) { 111 | fn = "system.img"; 112 | } else if(!strcmp(item,"vendor")) { 113 | fn = "vendor.img"; 114 | } else if(!strcmp(item,"userdata")) { 115 | fn = "userdata.img"; 116 | } else if(!strcmp(item,"cache")) { 117 | fn = "cache.img"; 118 | } else if(!strcmp(item,"info")) { 119 | fn = "android-info.txt"; 120 | } else { 121 | fprintf(stderr,"unknown partition '%s'\n", item); 122 | return 0; 123 | } 124 | 125 | if(product) { 126 | get_my_path(path); 127 | sprintf(path + strlen(path), 128 | "../../../target/product/%s/%s", product, fn); 129 | return strdup(path); 130 | } 131 | 132 | dir = getenv("ANDROID_PRODUCT_OUT"); 133 | if((dir == 0) || (dir[0] == 0)) { 134 | die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); 135 | return 0; 136 | } 137 | 138 | sprintf(path, "%s/%s", dir, fn); 139 | return strdup(path); 140 | } 141 | 142 | static int64_t file_size(int fd) 143 | { 144 | struct stat st; 145 | int ret; 146 | 147 | ret = fstat(fd, &st); 148 | 149 | return ret ? -1 : st.st_size; 150 | } 151 | 152 | static void *load_fd(int fd, unsigned *_sz) 153 | { 154 | char *data; 155 | int sz; 156 | int errno_tmp; 157 | 158 | data = 0; 159 | 160 | sz = file_size(fd); 161 | if (sz < 0) { 162 | goto oops; 163 | } 164 | 165 | data = (char*) malloc(sz); 166 | if(data == 0) goto oops; 167 | 168 | if(read(fd, data, sz) != sz) goto oops; 169 | close(fd); 170 | 171 | if(_sz) *_sz = sz; 172 | return data; 173 | 174 | oops: 175 | errno_tmp = errno; 176 | close(fd); 177 | if(data != 0) free(data); 178 | errno = errno_tmp; 179 | return 0; 180 | } 181 | 182 | static void *load_file(const char *fn, unsigned *_sz) 183 | { 184 | int fd; 185 | 186 | fd = open(fn, O_RDONLY | O_BINARY); 187 | if(fd < 0) return 0; 188 | 189 | return load_fd(fd, _sz); 190 | } 191 | 192 | int match_fastboot_with_serial(usb_ifc_info *info, const char *local_serial) 193 | { 194 | if(!(vendor_id && (info->dev_vendor == vendor_id)) && 195 | (info->dev_vendor != 0x18d1) && // Google 196 | (info->dev_vendor != 0x8087) && // Intel 197 | (info->dev_vendor != 0x0451) && 198 | (info->dev_vendor != 0x0502) && 199 | (info->dev_vendor != 0x0fce) && // Sony Ericsson 200 | (info->dev_vendor != 0x05c6) && // Qualcomm 201 | (info->dev_vendor != 0x22b8) && // Motorola 202 | (info->dev_vendor != 0x0955) && // Nvidia 203 | (info->dev_vendor != 0x413c) && // DELL 204 | (info->dev_vendor != 0x2314) && // INQ Mobile 205 | (info->dev_vendor != 0x0b05) && // Asus 206 | (info->dev_vendor != 0x0bb4)) // HTC 207 | return -1; 208 | if(info->ifc_class != 0xff) return -1; 209 | if(info->ifc_subclass != 0x42) return -1; 210 | if(info->ifc_protocol != 0x03) return -1; 211 | // require matching serial number or device path if requested 212 | // at the command line with the -s option. 213 | if (local_serial && (strcmp(local_serial, info->serial_number) != 0 && 214 | strcmp(local_serial, info->device_path) != 0)) return -1; 215 | return 0; 216 | } 217 | 218 | int match_fastboot(usb_ifc_info *info) 219 | { 220 | return match_fastboot_with_serial(info, serial); 221 | } 222 | 223 | int list_devices_callback(usb_ifc_info *info) 224 | { 225 | if (match_fastboot_with_serial(info, NULL) == 0) { 226 | const char* serial = info->serial_number; 227 | if (!info->writable) { 228 | serial = "no permissions"; // like "adb devices" 229 | } 230 | if (!serial[0]) { 231 | serial = "????????????"; 232 | } 233 | // output compatible with "adb devices" 234 | if (!long_listing) { 235 | printf("%s\tfastboot\n", serial); 236 | } else if (strcmp("", info->device_path) == 0) { 237 | printf("%-22s fastboot\n", serial); 238 | } else { 239 | printf("%-22s fastboot %s\n", serial, info->device_path); 240 | } 241 | } 242 | 243 | return -1; 244 | } 245 | 246 | usb_handle *open_device(void) 247 | { 248 | static usb_handle *usb = 0; 249 | int announce = 1; 250 | 251 | if(usb) return usb; 252 | 253 | for(;;) { 254 | usb = usb_open(match_fastboot); 255 | if(usb) return usb; 256 | if(announce) { 257 | announce = 0; 258 | fprintf(stderr,"< waiting for device >\n"); 259 | } 260 | usleep(1000); 261 | } 262 | } 263 | 264 | void list_devices(void) { 265 | // We don't actually open a USB device here, 266 | // just getting our callback called so we can 267 | // list all the connected devices. 268 | usb_open(list_devices_callback); 269 | } 270 | 271 | void usage(void) 272 | { 273 | fprintf(stderr, 274 | /* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */ 275 | "usage: fastboot [