Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d170bb03 authored by Dan Albert's avatar Dan Albert Committed by Gerrit Code Review
Browse files

Merge "Remove fastbootd."

parents 07dcb12e 71b99df5
Loading
Loading
Loading
Loading

fastbootd/Android.mk

deleted100644 → 0
+0 −83
Original line number Diff line number Diff line
# 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 \
    commands/boot.c \
    commands/flash.c \
    commands/partitions.c \
    commands/virtual_partitions.c \
    fastbootd.c \
    protocol.c \
    network_discovery.c \
    socket_client.c \
    secure.c \
    transport.c \
    transport_socket.c \
    trigger.c \
    usb_linux_client.c \
    utils.c \

LOCAL_MODULE := fastbootd
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -Wno-deprecated-declarations -DFLASH_CERT

LOCAL_STATIC_LIBRARIES := \
    libc \
    libcrypto_static \
    libcutils \
    libmdnssd \
    libsparse_static \
    libz

LOCAL_HAL_STATIC_LIBRARIES := libvendortrigger

LOCAL_FORCE_STATIC_EXECUTABLE := true

include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
    commands/partitions.c \
    other/gptedit.c \
    utils.c

LOCAL_MODULE := gptedit
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter

LOCAL_STATIC_LIBRARIES := \
    libsparse_static \
    libc \
    libcutils \
    libz

LOCAL_FORCE_STATIC_EXECUTABLE := true

include $(BUILD_EXECUTABLE)

# vendor trigger HAL
include $(CLEAR_VARS)
LOCAL_CFLAGS := -Wall -Werror
LOCAL_MODULE := libvendortrigger.default
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := vendor_trigger_default.c
LOCAL_STATIC_LIBRARIES := libcutils
include $(BUILD_STATIC_LIBRARY)

fastbootd/bootimg.h

deleted100644 → 0
+0 −97
Original line number Diff line number Diff line
/*
 * 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

fastbootd/commands.c

deleted100644 → 0
+0 −409
Original line number Diff line number Diff line
/*
 * 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 <inttypes.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/reboot.h>
#include <fcntl.h>

#include "bootimg.h"
#include "commands/boot.h"
#include "commands/flash.h"
#include "commands/partitions.h"
#include "commands/virtual_partitions.h"
#include "debug.h"
#include "protocol.h"
#include "trigger.h"
#include "utils.h"

#define ATAGS_LOCATION "/proc/atags"

static void cmd_boot(struct protocol_handle *phandle, const char *arg)
{
    int sz, atags_sz, new_atags_sz;
    int rv;
    unsigned kernel_actual;
    unsigned ramdisk_actual;
    unsigned second_actual;
    void *kernel_ptr;
    void *ramdisk_ptr;
    void *second_ptr;
    struct boot_img_hdr *hdr;
    char *ptr = NULL;
    char *atags_ptr = NULL;
    char *new_atags = NULL;
    int data_fd = 0;

    D(DEBUG, "cmd_boot %s\n", arg);

    if (phandle->download_fd < 0) {
        fastboot_fail(phandle, "no kernel file");
        return;
    }

    atags_ptr = read_atags(ATAGS_LOCATION, &atags_sz);
    if (atags_ptr == NULL) {
        fastboot_fail(phandle, "atags read error");
        goto error;
    }

    // TODO: With cms we can also verify partition name included as
    // cms signed attribute
    if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) {
        fastboot_fail(phandle, "Access forbiden you need the certificate");
        return;
    }

    sz = get_file_size(data_fd);

    ptr = (char *) mmap(NULL, sz, PROT_READ,
                        MAP_POPULATE | MAP_PRIVATE, data_fd, 0);

    hdr = (struct boot_img_hdr *) ptr;

    if (ptr == MAP_FAILED) {
        fastboot_fail(phandle, "internal fastbootd error");
        goto error;
    }

    if ((size_t) sz < sizeof(*hdr)) {
        fastboot_fail(phandle, "invalid bootimage header");
        goto error;
    }

    kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, hdr->page_size);
    ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, hdr->page_size);
    second_actual = ROUND_TO_PAGE(hdr->second_size, hdr->page_size);

    new_atags = (char *) create_atags((unsigned *) atags_ptr, atags_sz, hdr, &new_atags_sz);

    if (new_atags == NULL) {
        fastboot_fail(phandle, "atags generate error");
        goto error;
    }
    if (new_atags_sz > 0x4000) {
        fastboot_fail(phandle, "atags file to large");
        goto error;
    }

    if ((int) (hdr->page_size + kernel_actual + ramdisk_actual) < sz) {
        fastboot_fail(phandle, "incomplete bootimage");
        goto error;
    }

    kernel_ptr = (void *)((uintptr_t) ptr + hdr->page_size);
    ramdisk_ptr = (void *)((uintptr_t) kernel_ptr + kernel_actual);
    second_ptr = (void *)((uintptr_t) ramdisk_ptr + ramdisk_actual);

    D(INFO, "preparing to boot");
    // Prepares boot physical address. Addresses from header are ignored
    rv = prepare_boot_linux(hdr->kernel_addr, kernel_ptr, kernel_actual,
                            hdr->ramdisk_addr, ramdisk_ptr, ramdisk_actual,
                            hdr->second_addr, second_ptr, second_actual,
                            hdr->tags_addr, new_atags, ROUND_TO_PAGE(new_atags_sz, hdr->page_size));
    if (rv < 0) {
        fastboot_fail(phandle, "kexec prepare failed");
        goto error;
    }

    fastboot_okay(phandle, "");

    free(atags_ptr);
    munmap(ptr, sz);
    free(new_atags);
    close(data_fd);

    D(INFO, "Kexec going to reboot");
    reboot(LINUX_REBOOT_CMD_KEXEC);

    fastboot_fail(phandle, "reboot error");

    return;

error:

    if (atags_ptr != NULL)
        free(atags_ptr);
    if (ptr != NULL)
        munmap(ptr, sz);

}

static void cmd_erase(struct protocol_handle *phandle, const char *arg)
{
    int partition_fd;
    char path[PATH_MAX];
    D(DEBUG, "cmd_erase %s\n", arg);

    if (flash_find_entry(arg, path, PATH_MAX)) {
        fastboot_fail(phandle, "partition table doesn't exist");
        return;
    }

    if (!path[0]) {
        fastboot_fail(phandle, "Couldn't find partition");
        return;
    }

    partition_fd = flash_get_partiton(path);
    if (partition_fd < 0) {
        fastboot_fail(phandle, "partiton file does not exists");
    }

    if (flash_erase(partition_fd)) {
        fastboot_fail(phandle, "failed to erase partition");
        flash_close(partition_fd);
        return;
    }

    if (flash_close(partition_fd) < 0) {
        D(ERR, "could not close device %s", strerror(errno));
        fastboot_fail(phandle, "failed to erase partition");
        return;
    }
    fastboot_okay(phandle, "");
}

static int GPT_header_location() {
    const char *location_str = fastboot_getvar("gpt_sector");
    char *str;
    int location;

    if (!strcmp("", location_str)) {
        D(INFO, "GPT location not specified using second sector");
        return 1;
    }
    else {
        location = strtoul(location_str, &str, 10);
        D(INFO, "GPT location specified as %d", location);

        if (*str != '\0')
            return -1;

        return location - 1;
    }
}

static void cmd_gpt_layout(struct protocol_handle *phandle, const char *arg) {
    struct GPT_entry_table *oldtable;
    int location;
    struct GPT_content content;
    const char *device;
    device = fastboot_getvar("blockdev");

    if (!strcmp(device, "")) {
        fastboot_fail(phandle, "blockdev not defined in config file");
        return;
    }

    //TODO: add same verification as in cmd_flash
    if (phandle->download_fd < 0) {
        fastboot_fail(phandle, "no layout file");
        return;
    }

    location = GPT_header_location();
    oldtable = GPT_get_device(device, location);

    GPT_default_content(&content, oldtable);
    if (oldtable == NULL)
        D(WARN, "Could not get old gpt table");
    else
        GPT_release_device(oldtable);

    if (!GPT_parse_file(phandle->download_fd, &content)) {
        fastboot_fail(phandle, "Could not parse partition config file");
        return;
    }

    if (trigger_gpt_layout(&content)) {
        fastboot_fail(phandle, "Vendor forbids this opperation");
        GPT_release_content(&content);
        return;
    }

    if (!GPT_write_content(device, &content)) {
        fastboot_fail(phandle, "Unable to write gpt file");
        GPT_release_content(&content);
        return;
    }

    GPT_release_content(&content);
    fastboot_okay(phandle, "");
}

static void cmd_flash(struct protocol_handle *phandle, const char *arg)
{
    int partition;
    uint64_t sz;
    char data[BOOT_MAGIC_SIZE];
    char path[PATH_MAX];
    ssize_t header_sz = 0;
    int data_fd = 0;

    D(DEBUG, "cmd_flash %s\n", arg);

    if (try_handle_virtual_partition(phandle, arg)) {
        return;
    }

    if (phandle->download_fd < 0) {
        fastboot_fail(phandle, "no kernel file");
        return;
    }

    if (flash_find_entry(arg, path, PATH_MAX)) {
        fastboot_fail(phandle, "partition table doesn't exist");
        return;
    }

    if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) {
        fastboot_fail(phandle, "Access forbiden you need certificate");
        return;
    }

    // TODO: Maybe its goot idea to check whether the partition is bootable
    if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) {
        if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) {
            fastboot_fail(phandle, "incoming data read error, cannot read boot header");
            return;
        }
        if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
            fastboot_fail(phandle, "image is not a boot image");
            return;
        }
    }

    partition = flash_get_partiton(path);

    sz = get_file_size64(data_fd);

    sz -= header_sz;

    if (sz > get_file_size64(partition)) {
        flash_close(partition);
        D(WARN, "size of file too large");
        fastboot_fail(phandle, "size of file too large");
        return;
    }

    D(INFO, "writing %"PRId64" bytes to '%s'\n", sz, arg);

    if (flash_write(partition, phandle->download_fd, sz, header_sz)) {
        fastboot_fail(phandle, "flash write failure");
        return;
    }
    D(INFO, "partition '%s' updated\n", arg);

    flash_close(partition);
    close(data_fd);

    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) {
        fastboot_fail(phandle, "download failed");
        return;
    }

    fastboot_okay(phandle, "");
}

static void cmd_oem(struct protocol_handle *phandle, const char *arg) {
    const char *response = "";

    //TODO: Maybe it should get download descriptor also
    if (trigger_oem_cmd(arg, &response))
        fastboot_fail(phandle, response);
    else
        fastboot_okay(phandle, response);
}

void commands_init()
{
    virtual_partition_register("partition-table", cmd_gpt_layout);

    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_register("oem", cmd_oem);
    //fastboot_publish("version", "0.5");
    //fastboot_publish("product", "swordfish");
    //fastboot_publish("kernel", "lk");
}

fastbootd/commands/boot.c

deleted100644 → 0
+0 −255

File deleted.

Preview size limit exceeded, changes collapsed.

fastbootd/commands/boot.h

deleted100644 → 0
+0 −50
Original line number Diff line number Diff line
/*
 * 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.
 */

#ifndef __FASTBOOT_BOOT_H
#define __FASTBOOT_BOOT_H

#include <sys/cdefs.h>
#include <linux/kexec.h>

#include "bootimg.h"

#define KEXEC_TYPE_DEFAULT 0
#define KEXEC_TYPE_CRASH   1

int prepare_boot_linux(uintptr_t, void *, int, uintptr_t, void *, int,
                       uintptr_t, void *, int, uintptr_t, void *, int);
unsigned *create_atags(unsigned *, int, const struct boot_img_hdr *, int *);
long kexec_load(unsigned int, unsigned long, struct kexec_segment *, unsigned long);
char *read_atags(const char *, int *);

#endif /* _SYS_KEXEC_H */
Loading