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

Commit 577e8b44 authored by Elliott Hughes's avatar Elliott Hughes
Browse files

Add fastboot --os-version and --os-patch-level.

Also move -c to --cmdline to match the python mkbootimg tool. Remove
the short options for these rarely-used options.

Remove #if 0 cruft from <bootimg/bootimg.h>.

Bug: http://b/77340848
Test: manual testing (need to fix http://b/77809061 for unit tests)
Change-Id: Ieaa795566611bd89ba3fee39a1d9f6ad0713a587
parent 0289f35b
Loading
Loading
Loading
Loading
+17 −22
Original line number Diff line number Diff line
@@ -34,16 +34,15 @@
#include <stdlib.h>
#include <string.h>

void bootimg_set_cmdline(boot_img_hdr_v1* h, const char* cmdline) {
    if (strlen(cmdline) >= sizeof(h->cmdline)) die("command line too large: %zu", strlen(cmdline));
    strcpy(reinterpret_cast<char*>(h->cmdline), cmdline);
void bootimg_set_cmdline(boot_img_hdr_v1* h, const std::string& cmdline) {
    if (cmdline.size() >= sizeof(h->cmdline)) die("command line too large: %zu", cmdline.size());
    strcpy(reinterpret_cast<char*>(h->cmdline), cmdline.c_str());
}

boot_img_hdr_v1* mkbootimg(void* kernel, int64_t kernel_size, off_t kernel_offset, void* ramdisk,
                           int64_t ramdisk_size, off_t ramdisk_offset, void* second,
                           int64_t second_size, off_t second_offset, size_t page_size, size_t base,
                           off_t tags_offset, uint32_t header_version, int64_t* bootimg_size) {
    size_t page_mask = page_size - 1;
boot_img_hdr_v1* mkbootimg(void* kernel, int64_t kernel_size, void* ramdisk, int64_t ramdisk_size,
                           void* second, int64_t second_size, size_t base,
                           const boot_img_hdr_v1& src, int64_t* bootimg_size) {
    const size_t page_mask = src.page_size - 1;

    int64_t header_actual = sizeof(boot_img_hdr_v1) & (~page_mask);
    int64_t kernel_actual = (kernel_size + page_mask) & (~page_mask);
@@ -53,30 +52,26 @@ boot_img_hdr_v1* mkbootimg(void* kernel, int64_t kernel_size, off_t kernel_offse
    *bootimg_size = header_actual + kernel_actual + ramdisk_actual + second_actual;

    boot_img_hdr_v1* hdr = reinterpret_cast<boot_img_hdr_v1*>(calloc(*bootimg_size, 1));
    if (hdr == nullptr) {
        return hdr;
    }
    if (hdr == nullptr) die("couldn't allocate boot image: %" PRId64 " bytes", *bootimg_size);

    *hdr = src;
    memcpy(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);

    hdr->kernel_size =  kernel_size;
    hdr->ramdisk_size = ramdisk_size;
    hdr->second_size =  second_size;

    hdr->kernel_addr =  base + kernel_offset;
    hdr->ramdisk_addr = base + ramdisk_offset;
    hdr->second_addr =  base + second_offset;
    hdr->tags_addr =    base + tags_offset;

    hdr->page_size =    page_size;
    hdr->kernel_addr += base;
    hdr->ramdisk_addr += base;
    hdr->second_addr += base;
    hdr->tags_addr += base;

    if (header_version) {
        hdr->header_version = header_version;
    if (hdr->header_version != 0) {
        hdr->header_size = sizeof(boot_img_hdr_v1);
    }

    memcpy(hdr->magic + page_size, kernel, kernel_size);
    memcpy(hdr->magic + page_size + kernel_actual, ramdisk, ramdisk_size);
    memcpy(hdr->magic + page_size + kernel_actual + ramdisk_actual, second, second_size);
    memcpy(hdr->magic + hdr->page_size, kernel, kernel_size);
    memcpy(hdr->magic + hdr->page_size + kernel_actual, ramdisk, ramdisk_size);
    memcpy(hdr->magic + hdr->page_size + kernel_actual + ramdisk_actual, second, second_size);
    return hdr;
}
+6 −8
Original line number Diff line number Diff line
@@ -26,17 +26,15 @@
 * SUCH DAMAGE.
 */

#ifndef _FASTBOOT_BOOTIMG_UTILS_H_
#define _FASTBOOT_BOOTIMG_UTILS_H_
#pragma once

#include <bootimg.h>
#include <inttypes.h>
#include <sys/types.h>

void bootimg_set_cmdline(boot_img_hdr_v1* h, const char* cmdline);
boot_img_hdr_v1* mkbootimg(void* kernel, int64_t kernel_size, off_t kernel_offset, void* ramdisk,
                           int64_t ramdisk_size, off_t ramdisk_offset, void* second,
                           int64_t second_size, off_t second_offset, size_t page_size, size_t base,
                           off_t tags_offset, uint32_t header_version, int64_t* bootimg_size);
#include <string>

#endif
boot_img_hdr_v1* mkbootimg(void* kernel, int64_t kernel_size, void* ramdisk, int64_t ramdisk_size,
                           void* second, int64_t second_size, size_t base,
                           const boot_img_hdr_v1& src, int64_t* bootimg_size);
void bootimg_set_cmdline(boot_img_hdr_v1* h, const std::string& cmdline);
+134 −123
Original line number Diff line number Diff line
@@ -76,9 +76,9 @@ using android::base::unique_fd;
char cur_product[FB_RESPONSE_SZ + 1];

static const char* serial = nullptr;
static const char* cmdline = nullptr;

static unsigned short vendor_id = 0;
static int long_listing = 0;
static bool g_long_listing = false;
// Don't resparse files in too-big chunks.
// libsparse will support INT_MAX, but this results in large allocations, so
// let's keep it at 1GB to avoid memory pressure on the host.
@@ -86,12 +86,9 @@ static constexpr int64_t RESPARSE_LIMIT = 1 * 1024 * 1024 * 1024;
static int64_t sparse_limit = -1;
static int64_t target_sparse_limit = -1;

static unsigned page_size = 2048;
static unsigned base_addr      = 0x10000000;
static unsigned kernel_offset  = 0x00008000;
static unsigned ramdisk_offset = 0x01000000;
static unsigned second_offset  = 0x00f00000;
static unsigned tags_offset    = 0x00000100;
static unsigned g_base_addr = 0x10000000;
static boot_img_hdr_v1 g_boot_img_hdr = {};
static std::string g_cmdline;

static bool g_disable_verity = false;
static bool g_disable_verification = false;
@@ -223,7 +220,7 @@ static int list_devices_callback(usb_ifc_info* info) {
            serial = "????????????";
        }
        // output compatible with "adb devices"
        if (!long_listing) {
        if (!g_long_listing) {
            printf("%s\tfastboot", serial.c_str());
        } else {
            printf("%-22s fastboot", serial.c_str());
@@ -360,14 +357,18 @@ static int show_help() {
            "                            Download and boot kernel from RAM.\n"
            " flash:raw PARTITION KERNEL [RAMDISK [SECOND]]\n"
            "                            Create boot image and flash it.\n"
            // TODO: give -c a long option, and remove the short options for this group?
            " -c CMDLINE                 Override kernel command line.\n"
            " --cmdline CMDLINE          Override kernel command line.\n"
            " --base ADDRESS             Set kernel base address (default: 0x10000000).\n"
            " --kernel-offset            Set kernel offset (default: 0x00008000).\n"
            " --ramdisk-offset           Set ramdisk offset (default: 0x01000000).\n"
            " --tags-offset              Set tags offset (default: 0x00000100).\n"
            " --page-size BYTES          Set flash page size (default: 2048).\n"
            " --header-version VERSION   Set boot image header version.\n"
            " --os-version MAJOR[.MINOR[.PATCH]]\n"
            "                            Set boot image OS version (default: 0.0.0).\n"
            " --os-patch-level YYYY-MM-DD\n"
            "                            Set boot image OS security patch level.\n"
            // TODO: still missing: `second_addr`, `name`, `id`, `recovery_dtbo_*`.
            "\n"
            // TODO: what device(s) used this? is there any documentation?
            //" continue                               Continue with autoboot.\n"
@@ -404,8 +405,7 @@ static int show_help() {
}

static void* load_bootable_image(const std::string& kernel, const std::string& ramdisk,
                                 const std::string& second_stage, int64_t* sz,
                                 const char* cmdline, uint32_t header_version) {
                                 const std::string& second_stage, int64_t* sz) {
    int64_t ksize;
    void* kdata = load_file(kernel.c_str(), &ksize);
    if (kdata == nullptr) die("cannot load '%s': %s", kernel.c_str(), strerror(errno));
@@ -415,12 +415,14 @@ static void* load_bootable_image(const std::string& kernel, const std::string& r
        die("cannot load '%s': too short", kernel.c_str());
    }
    if (!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
        if (cmdline) bootimg_set_cmdline(reinterpret_cast<boot_img_hdr_v1*>(kdata), cmdline);
        if (!g_cmdline.empty()) {
            bootimg_set_cmdline(reinterpret_cast<boot_img_hdr_v1*>(kdata), g_cmdline);
        }
        uint32_t header_version_existing =
                reinterpret_cast<boot_img_hdr_v1*>(kdata)->header_version;
        if (header_version != header_version_existing) {
        if (g_boot_img_hdr.header_version != header_version_existing) {
            die("header version mismatch, expected: %" PRIu32 " found %" PRIu32 "",
                header_version, header_version_existing);
                g_boot_img_hdr.header_version, header_version_existing);
        }

        if (!ramdisk.empty()) die("cannot boot a boot.img *and* ramdisk");
@@ -444,16 +446,12 @@ static void* load_bootable_image(const std::string& kernel, const std::string& r
    }

    fprintf(stderr,"creating boot image...\n");
    int64_t bsize = 0;
    boot_img_hdr_v1* bdata = mkbootimg(kdata, ksize, kernel_offset,
                      rdata, rsize, ramdisk_offset,
                      sdata, ssize, second_offset,
                      page_size, base_addr, tags_offset, header_version, &bsize);
    boot_img_hdr_v1* bdata = mkbootimg(kdata, ksize, rdata, rsize, sdata, ssize,
                                       g_base_addr, g_boot_img_hdr, sz);
    if (bdata == nullptr) die("failed to create boot.img");

    if (cmdline) bootimg_set_cmdline(bdata, cmdline);
    fprintf(stderr, "creating boot image - %" PRId64 " bytes\n", bsize);
    *sz = bsize;
    if (!g_cmdline.empty()) bootimg_set_cmdline(bdata, g_cmdline);
    fprintf(stderr, "creating boot image - %" PRId64 " bytes\n", *sz);

    return bdata;
}
@@ -1422,34 +1420,37 @@ int main(int argc, char **argv)
    bool skip_secondary = false;
    bool set_fbe_marker = false;
    void *data;
    uint32_t header_version = 0;
    int64_t sz;
    int longindex;
    std::string slot_override;
    std::string next_active;

    g_boot_img_hdr.kernel_addr = 0x00008000;
    g_boot_img_hdr.ramdisk_addr = 0x01000000;
    g_boot_img_hdr.second_addr = 0x00f00000;
    g_boot_img_hdr.tags_addr = 0x00000100;
    g_boot_img_hdr.page_size = 2048;

    const struct option longopts[] = {
        {"base", required_argument, 0, 'b'},
        {"kernel_offset", required_argument, 0, 'k'},
        {"kernel-offset", required_argument, 0, 'k'},
        {"page_size", required_argument, 0, 'n'},
        {"page-size", required_argument, 0, 'n'},
        {"ramdisk_offset", required_argument, 0, 'r'},
        {"ramdisk-offset", required_argument, 0, 'r'},
        {"tags_offset", required_argument, 0, 't'},
        {"tags-offset", required_argument, 0, 't'},
        {"base", required_argument, 0, 0},
        {"cmdline", required_argument, 0, 0},
        {"disable-verification", no_argument, 0, 0},
        {"disable-verity", no_argument, 0, 0},
        {"header-version", required_argument, 0, 0},
        {"help", no_argument, 0, 'h'},
        {"unbuffered", no_argument, 0, 0},
        {"slot", required_argument, 0, 0},
        {"set_active", optional_argument, 0, 'a'},
        {"kernel-offset", required_argument, 0, 0},
        {"os-patch-level", required_argument, 0, 0},
        {"os-version", required_argument, 0, 0},
        {"page-size", required_argument, 0, 0},
        {"ramdisk-offset", required_argument, 0, 0},
        {"set-active", optional_argument, 0, 'a'},
        {"skip-secondary", no_argument, 0, 0},
        {"skip-reboot", no_argument, 0, 0},
        {"skip-secondary", no_argument, 0, 0},
        {"slot", required_argument, 0, 0},
        {"tags-offset", required_argument, 0, 0},
        {"unbuffered", no_argument, 0, 0},
        {"verbose", no_argument, 0, 'v'},
        {"version", no_argument, 0, 0},
        {"disable-verity", no_argument, 0, 0},
        {"disable-verification", no_argument, 0, 0},
        {"header-version", required_argument, 0, 0},
#if !defined(_WIN32)
        {"wipe-and-use-fbe", no_argument, 0, 0},
#endif
@@ -1458,51 +1459,89 @@ int main(int argc, char **argv)

    serial = getenv("ANDROID_SERIAL");

    while (1) {
        int c = getopt_long(argc, argv, "vwb:k:n:r:t:s:S:lc:i:m:ha::", longopts, &longindex);
        if (c < 0) {
            break;
    int c;
    while ((c = getopt_long(argc, argv, "a::hi:ls:S:vw", longopts, &longindex)) != -1) {
        if (c == 0) {
            std::string name{longopts[longindex].name};
            if (name == "base") {
                g_base_addr = strtoul(optarg, 0, 16);
            } else if (name == "cmdline") {
                g_cmdline = optarg;
            } else if (name == "disable-verification") {
                g_disable_verification = true;
            } else if (name == "disable-verity") {
                g_disable_verity = true;
            } else if (name == "header-version") {
                g_boot_img_hdr.header_version = strtoul(optarg, nullptr, 0);
            } else if (name == "kernel-offset") {
                g_boot_img_hdr.kernel_addr = strtoul(optarg, 0, 16);
            } else if (name == "os-patch-level") {
                unsigned year, month, day;
                if (sscanf(optarg, "%u-%u-%u", &year, &month, &day) != 3) {
                    syntax_error("OS patch level should be YYYY-MM-DD: %s", optarg);
                }
                if (year < 2000 || year >= 2128) syntax_error("year out of range: %d", year);
                if (month < 1 || month > 12) syntax_error("month out of range: %d", month);
                g_boot_img_hdr.SetOsPatchLevel(year, month);
            } else if (name == "os-version") {
                unsigned major = 0, minor = 0, patch = 0;
                std::vector<std::string> versions = android::base::Split(optarg, ".");
                if (versions.size() < 1 || versions.size() > 3 ||
                    (versions.size() >= 1 && !android::base::ParseUint(versions[0], &major)) ||
                    (versions.size() >= 2 && !android::base::ParseUint(versions[1], &minor)) ||
                    (versions.size() == 3 && !android::base::ParseUint(versions[2], &patch)) ||
                    (major > 0x7f || minor > 0x7f || patch > 0x7f)) {
                    syntax_error("bad OS version: %s", optarg);
                }
                g_boot_img_hdr.SetOsVersion(major, minor, patch);
            } else if (name == "page-size") {
                g_boot_img_hdr.page_size = strtoul(optarg, nullptr, 0);
                if (g_boot_img_hdr.page_size == 0) die("invalid page size");
            } else if (name == "ramdisk-offset") {
                g_boot_img_hdr.ramdisk_addr = strtoul(optarg, 0, 16);
            } else if (name == "skip-reboot") {
                skip_reboot = true;
            } else if (name == "skip-secondary") {
                skip_secondary = true;
            } else if (name == "slot") {
                slot_override = optarg;
            } else if (name == "tags-offset") {
                g_boot_img_hdr.tags_addr = strtoul(optarg, 0, 16);
            } else if (name == "unbuffered") {
                setvbuf(stdout, nullptr, _IONBF, 0);
                setvbuf(stderr, nullptr, _IONBF, 0);
            } else if (name == "version") {
                fprintf(stdout, "fastboot version %s\n", FASTBOOT_VERSION);
                fprintf(stdout, "Installed as %s\n", android::base::GetExecutablePath().c_str());
                return 0;
#if !defined(_WIN32)
            } else if (name == "wipe-and-use-fbe") {
                wants_wipe = true;
                set_fbe_marker = true;
#endif
            } else {
                die("unknown option %s", longopts[longindex].name);
            }
        /* Alphabetical cases */
        } else {
            switch (c) {
                case 'a':
                    wants_set_active = true;
            if (optarg)
                next_active = optarg;
            break;
        case 'b':
            base_addr = strtoul(optarg, 0, 16);
            break;
        case 'c':
            cmdline = optarg;
                    if (optarg) next_active = optarg;
                    break;
                case 'h':
                    return show_help();
        case 'i': {
                case 'i':
                    {
                        char *endptr = nullptr;
                unsigned long val;

                val = strtoul(optarg, &endptr, 0);
                if (!endptr || *endptr != '\0' || (val & ~0xffff))
                        unsigned long val = strtoul(optarg, &endptr, 0);
                        if (!endptr || *endptr != '\0' || (val & ~0xffff)) {
                            die("invalid vendor id '%s'", optarg);
                        }
                        vendor_id = (unsigned short)val;
                        break;
                    }
        case 'k':
            kernel_offset = strtoul(optarg, 0, 16);
            break;
                case 'l':
            long_listing = 1;
            break;
        case 'n':
            page_size = (unsigned)strtoul(optarg, nullptr, 0);
            if (!page_size) die("invalid page size");
            break;
        case 'r':
            ramdisk_offset = strtoul(optarg, 0, 16);
            break;
        case 't':
            tags_offset = strtoul(optarg, 0, 16);
                    g_long_listing = true;
                    break;
                case 's':
                    serial = optarg;
@@ -1519,39 +1558,11 @@ int main(int argc, char **argv)
                    break;
                case '?':
                    return 1;
        case 0:
            if (strcmp("unbuffered", longopts[longindex].name) == 0) {
                setvbuf(stdout, nullptr, _IONBF, 0);
                setvbuf(stderr, nullptr, _IONBF, 0);
            } else if (strcmp("version", longopts[longindex].name) == 0) {
                fprintf(stdout, "fastboot version %s\n", FASTBOOT_VERSION);
                fprintf(stdout, "Installed as %s\n", android::base::GetExecutablePath().c_str());
                return 0;
            } else if (strcmp("slot", longopts[longindex].name) == 0) {
                slot_override = std::string(optarg);
            } else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
                skip_secondary = true;
            } else if (strcmp("skip-reboot", longopts[longindex].name) == 0 ) {
                skip_reboot = true;
            } else if (strcmp("disable-verity", longopts[longindex].name) == 0 ) {
                g_disable_verity = true;
            } else if (strcmp("disable-verification", longopts[longindex].name) == 0 ) {
                g_disable_verification = true;
#if !defined(_WIN32)
            } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
                wants_wipe = true;
                set_fbe_marker = true;
#endif
            } else if (strcmp("header-version", longopts[longindex].name) == 0) {
                header_version = strtoul(optarg, nullptr, 0);
            } else {
                die("unknown option %s", longopts[longindex].name);
            }
            break;
                default:
                    abort();
            }
        }
    }

    argc -= optind;
    argv += optind;
@@ -1668,7 +1679,7 @@ int main(int argc, char **argv)
            std::string second_stage;
            if (!args.empty()) second_stage = next_arg(&args);

            data = load_bootable_image(kernel, ramdisk, second_stage, &sz, cmdline, header_version);
            data = load_bootable_image(kernel, ramdisk, second_stage, &sz);
            fb_queue_download("boot.img", data, sz);
            fb_queue_command("boot", "booting");
        } else if (command == "flash") {
@@ -1694,7 +1705,7 @@ int main(int argc, char **argv)
            std::string second_stage;
            if (!args.empty()) second_stage = next_arg(&args);

            data = load_bootable_image(kernel, ramdisk, second_stage, &sz, cmdline, header_version);
            data = load_bootable_image(kernel, ramdisk, second_stage, &sz);
            auto flashraw = [&](const std::string& partition) {
                fb_queue_flash(partition, data, sz);
            };
+42 −58
Original line number Diff line number Diff line
/* tools/mkbootimg/bootimg.h
**
** Copyright 2007, The Android Open Source Project
**
** 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.
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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.
 */

#include <stdint.h>
#pragma once

#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
#include <stdint.h>

#define BOOT_MAGIC "ANDROID!"
#define BOOT_MAGIC_SIZE 8
@@ -26,12 +24,10 @@
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024

#define BOOT_HEADER_VERSION_ZERO 0
/*
 *  Bootloader expects the structure of boot_img_hdr with header version
 *  BOOT_HEADER_VERSION_ZERO to be as follows:
 */
// The bootloader expects the structure of boot_img_hdr with header
// version 0 to be as follows:
struct boot_img_hdr_v0 {
    // Must be BOOT_MAGIC.
    uint8_t magic[BOOT_MAGIC_SIZE];

    uint32_t kernel_size; /* size in bytes */
@@ -45,26 +41,36 @@ struct boot_img_hdr_v0 {

    uint32_t tags_addr; /* physical addr for kernel tags */
    uint32_t page_size; /* flash page size we assume */
    /*
     * version for the boot image header.
     */

    // Version of the boot image header.
    uint32_t header_version;

    /* operating system version and security patch level; for
     * version "A.B.C" and patch level "Y-M-D":
     * ver = A << 14 | B << 7 | C         (7 bits for each of A, B, C)
     * lvl = ((Y - 2000) & 127) << 4 | M  (7 bits for Y, 4 bits for M)
     * os_version = ver << 11 | lvl */
    // Operating system version and security patch level.
    // For version "A.B.C" and patch level "Y-M-D":
    //   (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M)
    //   os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0]
    uint32_t os_version;

#if __cplusplus
    void SetOsVersion(unsigned major, unsigned minor, unsigned patch) {
        os_version &= ((1 << 11) - 1);
        os_version |= (((major & 0x7f) << 25) | ((minor & 0x7f) << 18) | ((patch & 0x7f) << 11));
    }

    void SetOsPatchLevel(unsigned year, unsigned month) {
        os_version &= ~((1 << 11) - 1);
        os_version |= (((year - 2000) & 0x7f) << 4) | ((month & 0xf) << 0);
    }
#endif

    uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */

    uint8_t cmdline[BOOT_ARGS_SIZE];

    uint32_t id[8]; /* timestamp / checksum / sha1 / etc */

    /* Supplemental command line data; kept here to maintain
     * binary compatibility with older versions of mkbootimg */
    // Supplemental command line data; kept here to maintain
    // binary compatibility with older versions of mkbootimg.
    uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
} __attribute__((packed));

@@ -74,7 +80,7 @@ struct boot_img_hdr_v0 {
 */
typedef struct boot_img_hdr_v0 boot_img_hdr;

/* When a boot header is of version BOOT_HEADER_VERSION_ZERO, the structure of boot image is as
/* When a boot header is of version 0, the structure of boot image is as
 * follows:
 *
 * +-----------------+
@@ -103,15 +109,13 @@ typedef struct boot_img_hdr_v0 boot_img_hdr;
 *    else: jump to kernel_addr
 */

#define BOOT_HEADER_VERSION_ONE 1

struct boot_img_hdr_v1 : public boot_img_hdr_v0 {
    uint32_t recovery_dtbo_size;   /* size in bytes for recovery DTBO image */
    uint64_t recovery_dtbo_offset; /* physical load addr */
    uint32_t header_size;
} __attribute__((packed));

/* When the boot image header has a version of BOOT_HEADER_VERSION_ONE, the structure of the boot
/* When the boot image header has a version of 1, the structure of the boot
 * image is as follows:
 *
 * +-----------------+
@@ -142,23 +146,3 @@ struct boot_img_hdr_v1 : public boot_img_hdr_v0 {
 * 7. if second_size != 0: jump to second_addr
 *    else: jump to kernel_addr
 */

#if 0
typedef struct ptentry ptentry;

struct ptentry {
    char name[16];      /* asciiz partition name    */
    unsigned start;     /* starting block number    */
    unsigned length;    /* length in blocks         */
    unsigned flags;     /* set to zero              */
};

/* MSM Partition Table ATAG
**
** length: 2 + 7 * n
** atag:   0x4d534d70
**         <ptentry> x n
*/
#endif

#endif