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
This commit is contained in:
parent
0289f35b83
commit
577e8b44b6
|
@ -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->kernel_addr += base;
|
||||
hdr->ramdisk_addr += base;
|
||||
hdr->second_addr += base;
|
||||
hdr->tags_addr += base;
|
||||
|
||||
hdr->page_size = page_size;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,98 +1459,108 @@ 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;
|
||||
}
|
||||
/* Alphabetical cases */
|
||||
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;
|
||||
break;
|
||||
case 'h':
|
||||
return show_help();
|
||||
case 'i': {
|
||||
char *endptr = nullptr;
|
||||
unsigned long val;
|
||||
|
||||
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);
|
||||
break;
|
||||
case 's':
|
||||
serial = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
sparse_limit = parse_num(optarg);
|
||||
if (sparse_limit < 0) die("invalid sparse limit");
|
||||
break;
|
||||
case 'v':
|
||||
set_verbose();
|
||||
break;
|
||||
case 'w':
|
||||
wants_wipe = true;
|
||||
break;
|
||||
case '?':
|
||||
return 1;
|
||||
case 0:
|
||||
if (strcmp("unbuffered", longopts[longindex].name) == 0) {
|
||||
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 (strcmp("version", longopts[longindex].name) == 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;
|
||||
} 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) {
|
||||
} else if (name == "wipe-and-use-fbe") {
|
||||
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();
|
||||
} else {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
wants_set_active = true;
|
||||
if (optarg) next_active = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
return show_help();
|
||||
case 'i':
|
||||
{
|
||||
char *endptr = nullptr;
|
||||
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 'l':
|
||||
g_long_listing = true;
|
||||
break;
|
||||
case 's':
|
||||
serial = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
sparse_limit = parse_num(optarg);
|
||||
if (sparse_limit < 0) die("invalid sparse limit");
|
||||
break;
|
||||
case 'v':
|
||||
set_verbose();
|
||||
break;
|
||||
case 'w':
|
||||
wants_wipe = true;
|
||||
break;
|
||||
case '?':
|
||||
return 1;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -1,37 +1,33 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _BOOT_IMAGE_H_
|
||||
#define _BOOT_IMAGE_H_
|
||||
|
||||
#define BOOT_MAGIC "ANDROID!"
|
||||
#define BOOT_MAGIC_SIZE 8
|
||||
#define BOOT_NAME_SIZE 16
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue