Properly support v4 image headers

This commit is contained in:
topjohnwu 2021-11-21 05:55:20 -08:00
parent 5787aa1078
commit 632971af15
2 changed files with 43 additions and 4 deletions

View File

@ -52,7 +52,8 @@ static size_t restore(int fd, const char *filename) {
void dyn_img_hdr::print() { void dyn_img_hdr::print() {
uint32_t ver = header_version(); uint32_t ver = header_version();
fprintf(stderr, "%-*s [%u]\n", PADDING, "HEADER_VER", ver); fprintf(stderr, "%-*s [%u]\n", PADDING, "HEADER_VER", ver);
fprintf(stderr, "%-*s [%u]\n", PADDING, "KERNEL_SZ", kernel_size()); if (!is_vendor)
fprintf(stderr, "%-*s [%u]\n", PADDING, "KERNEL_SZ", kernel_size());
fprintf(stderr, "%-*s [%u]\n", PADDING, "RAMDISK_SZ", ramdisk_size()); fprintf(stderr, "%-*s [%u]\n", PADDING, "RAMDISK_SZ", ramdisk_size());
if (ver < 3) if (ver < 3)
fprintf(stderr, "%-*s [%u]\n", PADDING, "SECOND_SZ", second_size()); fprintf(stderr, "%-*s [%u]\n", PADDING, "SECOND_SZ", second_size());
@ -219,8 +220,8 @@ static format_t check_fmt_lg(uint8_t *buf, unsigned sz) {
format_t fmt = check_fmt(buf, sz); format_t fmt = check_fmt(buf, sz);
if (fmt == LZ4_LEGACY) { if (fmt == LZ4_LEGACY) {
// We need to check if it is LZ4_LG // We need to check if it is LZ4_LG
unsigned off = 4; uint32_t off = 4;
unsigned block_sz; uint32_t block_sz;
while (off + sizeof(block_sz) <= sz) { while (off + sizeof(block_sz) <= sz) {
memcpy(&block_sz, buf + off, sizeof(block_sz)); memcpy(&block_sz, buf + off, sizeof(block_sz));
off += sizeof(block_sz); off += sizeof(block_sz);
@ -292,6 +293,13 @@ name = hdr_addr + off; \
off += hdr->name##_size(); \ off += hdr->name##_size(); \
off = do_align(off, hdr->page_size()); off = do_align(off, hdr->page_size());
#define get_ignore(name) \
if (hdr->name##_size()) { \
auto blk_sz = do_align(hdr->name##_size(), hdr->page_size()); \
ignore_size += blk_sz; \
off += blk_sz; \
}
void boot_img::parse_image(uint8_t *addr, format_t type) { void boot_img::parse_image(uint8_t *addr, format_t type) {
hdr = create_hdr(addr, type); hdr = create_hdr(addr, type);
@ -314,6 +322,11 @@ void boot_img::parse_image(uint8_t *addr, format_t type) {
get_block(recovery_dtbo); get_block(recovery_dtbo);
get_block(dtb); get_block(dtb);
ignore = hdr_addr + off;
get_ignore(signature)
get_ignore(vendor_ramdisk_table)
get_ignore(bootconfig)
if (int dtb_off = find_dtb_offset(kernel, hdr->kernel_size()); dtb_off > 0) { if (int dtb_off = find_dtb_offset(kernel, hdr->kernel_size()); dtb_off > 0) {
kernel_dtb = kernel + dtb_off; kernel_dtb = kernel + dtb_off;
hdr->kernel_dt_size = hdr->kernel_size() - dtb_off; hdr->kernel_dt_size = hdr->kernel_size() - dtb_off;
@ -364,7 +377,13 @@ void boot_img::parse_image(uint8_t *addr, format_t type) {
fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]); fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]);
} }
if (auto size = hdr->ramdisk_size()) { if (auto size = hdr->ramdisk_size()) {
r_fmt = check_fmt_lg(ramdisk, size); if (hdr->is_vendor && hdr->header_version() >= 4) {
// v4 vendor boot contains multiple ramdisks
// Do not try to mess with it for now
r_fmt = UNKNOWN;
} else {
r_fmt = check_fmt_lg(ramdisk, size);
}
if (r_fmt == MTK) { if (r_fmt == MTK) {
fprintf(stderr, "MTK_RAMDISK_HDR\n"); fprintf(stderr, "MTK_RAMDISK_HDR\n");
flags[MTK_RAMDISK] = true; flags[MTK_RAMDISK] = true;
@ -636,6 +655,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
file_align(); file_align();
} }
// Directly copy ignored blobs
if (boot.ignore_size) {
// ignore_size should already be aligned
xwrite(fd, boot.ignore, boot.ignore_size);
}
// Proprietary stuffs // Proprietary stuffs
if (boot.flags[SEANDROID_FLAG]) { if (boot.flags[SEANDROID_FLAG]) {
xwrite(fd, SEANDROID_MAGIC, 16); xwrite(fd, SEANDROID_MAGIC, 16);

View File

@ -367,6 +367,11 @@ struct dyn_img_hdr {
decl_var(header_size, 32) decl_var(header_size, 32)
decl_var(dtb_size, 32) decl_var(dtb_size, 32)
// v4 specific
decl_val(signature_size, uint32_t)
decl_val(vendor_ramdisk_table_size, uint32_t)
decl_val(bootconfig_size, uint32_t)
virtual ~dyn_img_hdr() { virtual ~dyn_img_hdr() {
free(raw); free(raw);
} }
@ -495,6 +500,8 @@ struct dyn_img_v3 : public dyn_img_hdr_boot {
struct dyn_img_v4 : public dyn_img_v3 { struct dyn_img_v4 : public dyn_img_v3 {
impl_cls(v4) impl_cls(v4)
impl_val(signature_size)
}; };
struct dyn_img_hdr_vendor : public dyn_img_hdr { struct dyn_img_hdr_vendor : public dyn_img_hdr {
@ -524,6 +531,9 @@ struct dyn_img_vnd_v3 : public dyn_img_hdr_vendor {
struct dyn_img_vnd_v4 : public dyn_img_vnd_v3 { struct dyn_img_vnd_v4 : public dyn_img_vnd_v3 {
impl_cls(vnd_v4) impl_cls(vnd_v4)
impl_val(vendor_ramdisk_table_size)
impl_val(bootconfig_size)
}; };
#undef __impl_cls #undef __impl_cls
@ -610,6 +620,10 @@ struct boot_img {
uint8_t *recovery_dtbo; uint8_t *recovery_dtbo;
uint8_t *dtb; uint8_t *dtb;
// Pointer to blocks defined in header, but we do not care
uint8_t *ignore;
size_t ignore_size = 0;
boot_img(const char *); boot_img(const char *);
~boot_img(); ~boot_img();