forked from CyanogenMod/android_system_core
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fastbootd: userspace implementation of the fastboot device-side protocol
Initial commit of fastbootd. A few commands work, but not fully functional yet. Change-Id: I589dee7b327b4460e94b4434aaf9bcf780faa839
- Loading branch information
1 parent
fb32808
commit a3d386e
Showing
11 changed files
with
1,388 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Copyright (C) 2013 Google Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
LOCAL_PATH:= $(call my-dir) | ||
|
||
include $(CLEAR_VARS) | ||
|
||
LOCAL_SRC_FILES := \ | ||
config.c \ | ||
commands.c \ | ||
fastbootd.c \ | ||
protocol.c \ | ||
transport.c \ | ||
usb_linux_client.c | ||
|
||
LOCAL_MODULE := fastbootd | ||
LOCAL_MODULE_TAGS := optional | ||
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter | ||
|
||
LOCAL_STATIC_LIBRARIES := \ | ||
libsparse_static \ | ||
libc \ | ||
libcutils | ||
|
||
LOCAL_FORCE_STATIC_EXECUTABLE := true | ||
|
||
include $(BUILD_EXECUTABLE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright (C) 2008 The Android Open Source Project | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in | ||
* the documentation and/or other materials provided with the | ||
* distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
* SUCH DAMAGE. | ||
*/ | ||
|
||
#ifndef _BOOT_IMAGE_H_ | ||
#define _BOOT_IMAGE_H_ | ||
|
||
typedef struct boot_img_hdr boot_img_hdr; | ||
|
||
#define BOOT_MAGIC "ANDROID!" | ||
#define BOOT_MAGIC_SIZE 8 | ||
#define BOOT_NAME_SIZE 16 | ||
#define BOOT_ARGS_SIZE 512 | ||
|
||
struct boot_img_hdr | ||
{ | ||
unsigned char magic[BOOT_MAGIC_SIZE]; | ||
|
||
unsigned kernel_size; /* size in bytes */ | ||
unsigned kernel_addr; /* physical load addr */ | ||
|
||
unsigned ramdisk_size; /* size in bytes */ | ||
unsigned ramdisk_addr; /* physical load addr */ | ||
|
||
unsigned second_size; /* size in bytes */ | ||
unsigned second_addr; /* physical load addr */ | ||
|
||
unsigned tags_addr; /* physical addr for kernel tags */ | ||
unsigned page_size; /* flash page size we assume */ | ||
unsigned unused[2]; /* future expansion: should be 0 */ | ||
|
||
unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ | ||
|
||
unsigned char cmdline[BOOT_ARGS_SIZE]; | ||
|
||
unsigned id[8]; /* timestamp / checksum / sha1 / etc */ | ||
}; | ||
|
||
/* | ||
** +-----------------+ | ||
** | boot header | 1 page | ||
** +-----------------+ | ||
** | kernel | n pages | ||
** +-----------------+ | ||
** | ramdisk | m pages | ||
** +-----------------+ | ||
** | second stage | o pages | ||
** +-----------------+ | ||
** | ||
** n = (kernel_size + page_size - 1) / page_size | ||
** m = (ramdisk_size + page_size - 1) / page_size | ||
** o = (second_size + page_size - 1) / page_size | ||
** | ||
** 0. all entities are page_size aligned in flash | ||
** 1. kernel and ramdisk are required (size != 0) | ||
** 2. second is optional (second_size == 0 -> no second) | ||
** 3. load each element (kernel, ramdisk, second) at | ||
** the specified physical address (kernel_addr, etc) | ||
** 4. prepare tags at tag_addr. kernel_args[] is | ||
** appended to the kernel commandline in the tags. | ||
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr | ||
** 6. if second_size != 0: jump to second_addr | ||
** else: jump to kernel_addr | ||
*/ | ||
|
||
boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, | ||
void *ramdisk, unsigned ramdisk_size, | ||
void *second, unsigned second_size, | ||
unsigned page_size, | ||
unsigned *bootimg_size); | ||
|
||
void bootimg_set_cmdline(boot_img_hdr *hdr, const char *cmdline); | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/* | ||
* Copyright (c) 2009-2013, Google Inc. | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in | ||
* the documentation and/or other materials provided with the | ||
* distribution. | ||
* * Neither the name of Google, Inc. nor the names of its contributors | ||
* may be used to endorse or promote products derived from this | ||
* software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
* SUCH DAMAGE. | ||
*/ | ||
|
||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <sys/types.h> | ||
|
||
#include "bootimg.h" | ||
#include "debug.h" | ||
#include "protocol.h" | ||
|
||
static void cmd_boot(struct protocol_handle *phandle, const char *arg) | ||
{ | ||
#if 0 | ||
unsigned kernel_actual; | ||
unsigned ramdisk_actual; | ||
static struct boot_img_hdr hdr; | ||
char *ptr = ((char*) data); | ||
|
||
if (sz < sizeof(hdr)) { | ||
fastboot_fail(phandle, "invalid bootimage header"); | ||
return; | ||
} | ||
|
||
memcpy(&hdr, data, sizeof(hdr)); | ||
|
||
/* ensure commandline is terminated */ | ||
hdr.cmdline[BOOT_ARGS_SIZE-1] = 0; | ||
|
||
kernel_actual = ROUND_TO_PAGE(hdr.kernel_size); | ||
ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size); | ||
|
||
if (2048 + kernel_actual + ramdisk_actual < sz) { | ||
fastboot_fail(phandle, "incomplete bootimage"); | ||
return; | ||
} | ||
|
||
/*memmove((void*) KERNEL_ADDR, ptr + 2048, hdr.kernel_size); | ||
memmove((void*) RAMDISK_ADDR, ptr + 2048 + kernel_actual, hdr.ramdisk_size);*/ | ||
|
||
fastboot_okay(phandle, ""); | ||
udc_stop(); | ||
|
||
|
||
/*boot_linux((void*) KERNEL_ADDR, (void*) TAGS_ADDR, | ||
(const char*) hdr.cmdline, LINUX_MACHTYPE, | ||
(void*) RAMDISK_ADDR, hdr.ramdisk_size);*/ | ||
#endif | ||
} | ||
|
||
static void cmd_erase(struct protocol_handle *phandle, const char *arg) | ||
{ | ||
#if 0 | ||
struct ptentry *ptn; | ||
struct ptable *ptable; | ||
|
||
ptable = flash_get_ptable(); | ||
if (ptable == NULL) { | ||
fastboot_fail(phandle, "partition table doesn't exist"); | ||
return; | ||
} | ||
|
||
ptn = ptable_find(ptable, arg); | ||
if (ptn == NULL) { | ||
fastboot_fail(phandle, "unknown partition name"); | ||
return; | ||
} | ||
|
||
if (flash_erase(ptn)) { | ||
fastboot_fail(phandle, "failed to erase partition"); | ||
return; | ||
} | ||
fastboot_okay(phandle, ""); | ||
#endif | ||
} | ||
|
||
static void cmd_flash(struct protocol_handle *phandle, const char *arg) | ||
{ | ||
#if 0 | ||
struct ptentry *ptn; | ||
struct ptable *ptable; | ||
unsigned extra = 0; | ||
|
||
ptable = flash_get_ptable(); | ||
if (ptable == NULL) { | ||
fastboot_fail(phandle, "partition table doesn't exist"); | ||
return; | ||
} | ||
|
||
ptn = ptable_find(ptable, arg); | ||
if (ptn == NULL) { | ||
fastboot_fail(phandle, "unknown partition name"); | ||
return; | ||
} | ||
|
||
if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) { | ||
if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { | ||
fastboot_fail(phandle, "image is not a boot image"); | ||
return; | ||
} | ||
} | ||
|
||
if (!strcmp(ptn->name, "system") || !strcmp(ptn->name, "userdata")) | ||
extra = 64; | ||
else | ||
sz = ROUND_TO_PAGE(sz); | ||
|
||
D(INFO, "writing %d bytes to '%s'\n", sz, ptn->name); | ||
if (flash_write(ptn, extra, data, sz)) { | ||
fastboot_fail(phandle, "flash write failure"); | ||
return; | ||
} | ||
D(INFO, "partition '%s' updated\n", ptn->name); | ||
#endif | ||
fastboot_okay(phandle, ""); | ||
} | ||
|
||
static void cmd_continue(struct protocol_handle *phandle, const char *arg) | ||
{ | ||
fastboot_okay(phandle, ""); | ||
#if 0 | ||
udc_stop(); | ||
|
||
boot_linux_from_flash(); | ||
#endif | ||
} | ||
|
||
static void cmd_getvar(struct protocol_handle *phandle, const char *arg) | ||
{ | ||
const char *value; | ||
D(DEBUG, "cmd_getvar %s\n", arg); | ||
|
||
value = fastboot_getvar(arg); | ||
|
||
fastboot_okay(phandle, value); | ||
} | ||
|
||
static void cmd_download(struct protocol_handle *phandle, const char *arg) | ||
{ | ||
unsigned len = strtoul(arg, NULL, 16); | ||
int old_fd; | ||
|
||
if (len > 256 * 1024 * 1024) { | ||
fastboot_fail(phandle, "data too large"); | ||
return; | ||
} | ||
|
||
fastboot_data(phandle, len); | ||
|
||
old_fd = protocol_get_download(phandle); | ||
if (old_fd >= 0) { | ||
off_t len = lseek(old_fd, 0, SEEK_END); | ||
D(INFO, "disposing of unused fd %d, size %ld", old_fd, len); | ||
close(old_fd); | ||
} | ||
|
||
phandle->download_fd = protocol_handle_download(phandle, len); | ||
if (phandle->download_fd < 0) { | ||
//handle->state = STATE_ERROR; | ||
fastboot_fail(phandle, "download failed"); | ||
return; | ||
} | ||
|
||
fastboot_okay(phandle, ""); | ||
} | ||
|
||
void commands_init() | ||
{ | ||
fastboot_register("boot", cmd_boot); | ||
fastboot_register("erase:", cmd_erase); | ||
fastboot_register("flash:", cmd_flash); | ||
fastboot_register("continue", cmd_continue); | ||
fastboot_register("getvar:", cmd_getvar); | ||
fastboot_register("download:", cmd_download); | ||
//fastboot_publish("version", "0.5"); | ||
//fastboot_publish("product", "swordfish"); | ||
//fastboot_publish("kernel", "lk"); | ||
} |
Oops, something went wrong.