From b7e2e972c71564f682d886fda22a3ea3794bfe3f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 13 Mar 2019 16:51:22 -0400 Subject: [PATCH] Support boot_img_hdr_v2 --- native/jni/magiskboot/bootimg.cpp | 31 ++++++++++++++----- native/jni/magiskboot/bootimg.h | 49 +++++++++++++++++------------- native/jni/magiskboot/magiskboot.h | 3 +- native/jni/magiskboot/main.cpp | 13 ++++---- scripts/boot_patch.sh | 1 + 5 files changed, 61 insertions(+), 36 deletions(-) diff --git a/native/jni/magiskboot/bootimg.cpp b/native/jni/magiskboot/bootimg.cpp index 111173c54..53c58d904 100644 --- a/native/jni/magiskboot/bootimg.cpp +++ b/native/jni/magiskboot/bootimg.cpp @@ -149,6 +149,10 @@ int boot_img::parse_image(uint8_t *head) { pos += hdr.recovery_dtbo_size(); pos_align(); + dtb = head + pos; + pos += hdr.dtb_size(); + pos_align(); + if (head + pos < map_addr + map_size) { tail = head + pos; tail_size = map_size - (tail - map_addr); @@ -227,10 +231,10 @@ void boot_img::find_dtb() { continue; } - dtb = kernel + i; - dt_size = hdr->kernel_size - i; + kernel_dtb = kernel + i; + kernel_dt_size = hdr->kernel_size - i; hdr->kernel_size = i; - fprintf(stderr, "DTB [%u]\n", dt_size); + fprintf(stderr, "KERNEL_DTB [%u]\n", kernel_dt_size); break; } } @@ -242,6 +246,7 @@ void boot_img::print_hdr() { fprintf(stderr, "SECOND_SZ [%u]\n", hdr->second_size); fprintf(stderr, "EXTRA_SZ [%u]\n", hdr.extra_size()); fprintf(stderr, "RECOV_DTBO_SZ [%u]\n", hdr.recovery_dtbo_size()); + fprintf(stderr, "DTB [%u]\n", hdr.dtb_size()); uint32_t ver = hdr.os_version(); if (ver) { @@ -308,7 +313,7 @@ int unpack(const char *image, bool hdr) { } // Dump dtb - dump(boot.dtb, boot.dt_size, DTB_FILE); + dump(boot.kernel_dtb, boot.kernel_dt_size, KER_DTB_FILE); // Dump ramdisk if (COMPRESSED(boot.r_fmt)) { @@ -327,6 +332,9 @@ int unpack(const char *image, bool hdr) { // Dump recovery_dtbo dump(boot.recov_dtbo, boot.hdr.recovery_dtbo_size(), RECV_DTBO_FILE); + + // Dump dtb + dump(boot.dtb, boot.hdr.dtb_size(), DTB_FILE); return ret; } @@ -343,7 +351,8 @@ void repack(const char* orig_image, const char* out_image) { boot.hdr->kernel_size = 0; boot.hdr->ramdisk_size = 0; boot.hdr->second_size = 0; - boot.dt_size = 0; + boot.hdr.dtb_size() = 0; + boot.kernel_dt_size = 0; fprintf(stderr, "Repack to boot image: [%s]\n", out_image); @@ -417,9 +426,9 @@ void repack(const char* orig_image, const char* out_image) { munmap(raw_buf, raw_size); } - // dtb - if (access(DTB_FILE, R_OK) == 0) - boot.hdr->kernel_size += restore(DTB_FILE, fd); + // kernel dtb + if (access(KER_DTB_FILE, R_OK) == 0) + boot.hdr->kernel_size += restore(KER_DTB_FILE, fd); file_align(); // ramdisk @@ -462,6 +471,12 @@ void repack(const char* orig_image, const char* out_image) { file_align(); } + // dtb + if (access(DTB_FILE, R_OK) == 0) { + boot.hdr.dtb_size() = restore(DTB_FILE, fd); + file_align(); + } + // Append tail info if (boot.flags & SEANDROID_FLAG) { restore_buf(fd, SEANDROID_MAGIC "\xFF\xFF\xFF\xFF", 20); diff --git a/native/jni/magiskboot/bootimg.h b/native/jni/magiskboot/bootimg.h index 3b70f543e..f821e6842 100644 --- a/native/jni/magiskboot/bootimg.h +++ b/native/jni/magiskboot/bootimg.h @@ -1,9 +1,8 @@ +#pragma once + #include #include "format.h" -#ifndef _BOOT_IMAGE_H_ -#define _BOOT_IMAGE_H_ - struct boot_img_hdr_base { char magic[8]; @@ -46,13 +45,18 @@ struct boot_img_hdr_v0 : public boot_img_hdr_base { } __attribute__((packed)); 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; /* offset to recovery dtbo in boot image */ + uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */ + uint64_t recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */ uint32_t header_size; } __attribute__((packed)); +struct boot_img_hdr_v2 : public boot_img_hdr_v1 { + uint32_t dtb_size; /* size in bytes for DTB image */ + uint64_t dtb_addr; /* physical load address for DTB image */ +} __attribute__((packed)); + // Default to hdr v1 -typedef boot_img_hdr_v1 boot_img_hdr; +typedef boot_img_hdr_v2 boot_img_hdr; // Special Samsung header struct boot_img_hdr_pxa : public boot_img_hdr_base { @@ -84,12 +88,15 @@ struct boot_img_hdr_pxa : public boot_img_hdr_base { ** +-----------------+ ** | recovery dtbo | q pages ** +-----------------+ +** | dtb | r 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 ** p = (extra_size + page_size - 1) / page_size ** q = (recovery_dtbo_size + page_size - 1) / page_size +** r = (dtb_size + page_size - 1) / page_size ** ** 0. all entities are page_size aligned in flash ** 1. kernel and ramdisk are required (size != 0) @@ -145,14 +152,14 @@ struct blob_hdr { struct dyn_img_hdr { -#define dyn_access(x) (pxa ? hdr_pxa->x : v1_hdr->x) +#define dyn_access(x) (pxa ? hdr_pxa->x : v2_hdr->x) #define dyn_get(name, type) \ type name() const { return dyn_access(name); } #define dyn_ref(name, type) \ type &name() { return dyn_access(name); } -#define v1_ref(name, type, alt) \ -type &name() { if (pxa) { alt = 0; return alt; } return v1_hdr->name; } +#define v2_ref(name, type, alt) \ +type &name() { if (pxa) { alt = 0; return alt; } return v2_hdr->name; } dyn_ref(page_size, uint32_t); dyn_get(name, char *); @@ -160,23 +167,24 @@ type &name() { if (pxa) { alt = 0; return alt; } return v1_hdr->name; } dyn_get(id, char *); dyn_get(extra_cmdline, char *); - v1_ref(os_version, uint32_t, j32); - v1_ref(recovery_dtbo_size, uint32_t, j32); - v1_ref(recovery_dtbo_offset, uint64_t, j64); - v1_ref(header_size, uint32_t, j32); + v2_ref(os_version, uint32_t, j32); + v2_ref(recovery_dtbo_size, uint32_t, j32); + v2_ref(recovery_dtbo_offset, uint64_t, j64); + v2_ref(header_size, uint32_t, j32); + v2_ref(dtb_size, uint32_t, j32); dyn_img_hdr() : pxa(false), img_hdr(nullptr) {} ~dyn_img_hdr() { if (pxa) delete hdr_pxa; else - delete v1_hdr; + delete v2_hdr; } uint32_t header_version() { // There won't be v4 header any time soon... // If larger than 4, assume this field will be treated as extra_size - return pxa || v1_hdr->header_version > 4 ? 0 : v1_hdr->header_version; + return pxa || v2_hdr->header_version > 4 ? 0 : v2_hdr->header_version; } uint32_t &extra_size() { @@ -193,7 +201,7 @@ type &name() { if (pxa) { alt = 0; return alt; } return v1_hdr->name; } } void set_hdr(boot_img_hdr *h) { - v1_hdr = h; + v2_hdr = h; } void set_hdr(boot_img_hdr_pxa *h) { @@ -216,7 +224,7 @@ private: * but both of them is a base header. * Same address can be interpreted in 3 ways */ boot_img_hdr_base *img_hdr; /* Common base header */ - boot_img_hdr *v1_hdr; /* AOSP v1 header */ + boot_img_hdr *v2_hdr; /* AOSP v2 header */ boot_img_hdr_pxa *hdr_pxa; /* Samsung PXA header */ }; @@ -243,8 +251,8 @@ struct boot_img { format_t r_fmt; // Pointer to dtb that is appended after kernel - uint8_t *dtb; - uint32_t dt_size; + uint8_t *kernel_dtb; + uint32_t kernel_dt_size; // Pointer to end of image uint8_t *tail; @@ -256,6 +264,7 @@ struct boot_img { uint8_t *second; uint8_t *extra; uint8_t *recov_dtbo; + uint8_t *dtb; ~boot_img(); @@ -264,5 +273,3 @@ struct boot_img { void find_dtb(); void print_hdr(); }; - -#endif diff --git a/native/jni/magiskboot/magiskboot.h b/native/jni/magiskboot/magiskboot.h index 3b5ffee9b..ae1985b78 100644 --- a/native/jni/magiskboot/magiskboot.h +++ b/native/jni/magiskboot/magiskboot.h @@ -7,8 +7,9 @@ #define RAMDISK_FILE "ramdisk.cpio" #define SECOND_FILE "second" #define EXTRA_FILE "extra" -#define DTB_FILE "dtb" +#define KER_DTB_FILE "kernel_dtb" #define RECV_DTBO_FILE "recovery_dtbo" +#define DTB_FILE "dtb" #define NEW_BOOT "new-boot.img" // Main entries diff --git a/native/jni/magiskboot/main.cpp b/native/jni/magiskboot/main.cpp index 679065595..6221f5fc2 100644 --- a/native/jni/magiskboot/main.cpp +++ b/native/jni/magiskboot/main.cpp @@ -122,9 +122,10 @@ int main(int argc, char *argv[]) { unlink(KERNEL_FILE); unlink(RAMDISK_FILE); unlink(SECOND_FILE); - unlink(DTB_FILE); + unlink(KER_DTB_FILE); unlink(EXTRA_FILE); unlink(RECV_DTBO_FILE); + unlink(DTB_FILE); } else if (argc > 2 && strcmp(argv[1], "sha1") == 0) { uint8_t sha1[SHA_DIGEST_SIZE]; void *buf; @@ -147,16 +148,16 @@ int main(int argc, char *argv[]) { repack(argv[2], argv[3] ? argv[3] : NEW_BOOT); } else if (argc > 2 && strcmp(argv[1], "decompress") == 0) { decompress(argv[2], argv[3]); - } else if (argc > 2 && strncmp(argv[1], "compress", 10) == 0) { - compress(argv[1][10] == '=' ? &argv[1][11] : "gzip", argv[2], argv[3]); + } else if (argc > 2 && strncmp(argv[1], "compress", 8) == 0) { + compress(argv[1][8] == '=' ? &argv[1][9] : "gzip", argv[2], argv[3]); } else if (argc > 4 && strcmp(argv[1], "hexpatch") == 0) { hexpatch(argv[2], argv[3], argv[4]); } else if (argc > 2 && strcmp(argv[1], "cpio") == 0) { if (cpio_commands(argc - 2, argv + 2)) usage(argv[0]); - } else if (argc > 2 && strncmp(argv[1], "dtb", 5) == 0) { - if (argv[1][5] != '-') + } else if (argc > 2 && strncmp(argv[1], "dtb", 3) == 0) { + if (argv[1][3] != '-') usage(argv[0]); - if (dtb_commands(&argv[1][6], argc - 2, argv + 2)) + if (dtb_commands(&argv[1][4], argc - 2, argv + 2)) usage(argv[0]); } else { usage(argv[0]); diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index cc042f9e0..db4748d84 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -154,6 +154,7 @@ rm -f ramdisk.cpio.orig config if ! $KEEPVERITY; then [ -f dtb ] && ./magiskboot dtb-patch dtb && ui_print "- Removing dm(avb)-verity in dtb" + [ -f kernel_dtb ] && ./magiskboot dtb-patch kernel_dtb && ui_print "- Removing dm(avb)-verity in dtb" [ -f extra ] && ./magiskboot dtb-patch extra && ui_print "- Removing dm(avb)-verity in extra-dtb" fi