diff --git a/fastboot/bootimg_utils.cpp b/fastboot/bootimg_utils.cpp index 46d4bd30e..2c0989ed1 100644 --- a/fastboot/bootimg_utils.cpp +++ b/fastboot/bootimg_utils.cpp @@ -34,14 +34,54 @@ #include #include -void bootimg_set_cmdline(boot_img_hdr_v2* h, const std::string& cmdline) { +static void bootimg_set_cmdline_v3(boot_img_hdr_v3* h, const std::string& cmdline) { if (cmdline.size() >= sizeof(h->cmdline)) die("command line too large: %zu", cmdline.size()); strcpy(reinterpret_cast(h->cmdline), cmdline.c_str()); } +void bootimg_set_cmdline(boot_img_hdr_v2* h, const std::string& cmdline) { + if (h->header_version == 3) { + return bootimg_set_cmdline_v3(reinterpret_cast(h), cmdline); + } + if (cmdline.size() >= sizeof(h->cmdline)) die("command line too large: %zu", cmdline.size()); + strcpy(reinterpret_cast(h->cmdline), cmdline.c_str()); +} + +static boot_img_hdr_v3* mkbootimg_v3(const std::vector& kernel, + const std::vector& ramdisk, const boot_img_hdr_v2& src, + std::vector* out) { +#define V3_PAGE_SIZE 4096 + const size_t page_mask = V3_PAGE_SIZE - 1; + int64_t kernel_actual = (kernel.size() + page_mask) & (~page_mask); + int64_t ramdisk_actual = (ramdisk.size() + page_mask) & (~page_mask); + + int64_t bootimg_size = V3_PAGE_SIZE + kernel_actual + ramdisk_actual; + out->resize(bootimg_size); + + boot_img_hdr_v3* hdr = reinterpret_cast(out->data()); + + memcpy(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); + hdr->kernel_size = kernel.size(); + hdr->ramdisk_size = ramdisk.size(); + hdr->os_version = src.os_version; + hdr->header_size = sizeof(boot_img_hdr_v3); + hdr->header_version = 3; + + memcpy(hdr->magic + V3_PAGE_SIZE, kernel.data(), kernel.size()); + memcpy(hdr->magic + V3_PAGE_SIZE + kernel_actual, ramdisk.data(), ramdisk.size()); + + return hdr; +} + boot_img_hdr_v2* mkbootimg(const std::vector& kernel, const std::vector& ramdisk, const std::vector& second, const std::vector& dtb, size_t base, const boot_img_hdr_v2& src, std::vector* out) { + if (src.header_version == 3) { + if (!second.empty() || !dtb.empty()) { + die("Second stage bootloader and dtb not supported in v3 boot image\n"); + } + return reinterpret_cast(mkbootimg_v3(kernel, ramdisk, src, out)); + } const size_t page_mask = src.page_size - 1; int64_t header_actual = (sizeof(boot_img_hdr_v1) + page_mask) & (~page_mask); diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 7fdc28b3d..7f6e7230f 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -464,7 +464,7 @@ static std::vector LoadBootableImage(const std::string& kernel, const std: } // Is this actually a boot image? - if (kernel_data.size() < sizeof(boot_img_hdr_v2)) { + if (kernel_data.size() < sizeof(boot_img_hdr_v3)) { die("cannot load '%s': too short", kernel.c_str()); } if (!memcmp(kernel_data.data(), BOOT_MAGIC, BOOT_MAGIC_SIZE)) { @@ -493,7 +493,7 @@ static std::vector LoadBootableImage(const std::string& kernel, const std: std::vector dtb_data; if (!g_dtb_path.empty()) { - if (g_boot_img_hdr.header_version < 2) { + if (g_boot_img_hdr.header_version != 2) { die("Argument dtb not supported for boot image header version %d\n", g_boot_img_hdr.header_version); }