From c2154474050b15ae6b84770cc30497dc39787401 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sat, 7 Oct 2017 22:08:10 +0800 Subject: [PATCH] Fix Pixel C installation --- jni/magiskboot/boot_utils.c | 4 +- jni/magiskboot/bootimg.c | 81 +++++++++++++++++++------------------ jni/magiskboot/bootimg.h | 14 ++++--- jni/magiskboot/dtb.c | 37 ++++++++++++----- jni/magiskboot/hexpatch.c | 2 +- jni/magiskboot/magiskboot.h | 2 + jni/magiskboot/main.c | 6 +++ jni/magiskboot/types.h | 2 + scripts/boot_patch.sh | 22 +++++----- scripts/util_functions.sh | 10 ++--- 10 files changed, 103 insertions(+), 77 deletions(-) diff --git a/jni/magiskboot/boot_utils.c b/jni/magiskboot/boot_utils.c index bc683cd80..62a029adf 100644 --- a/jni/magiskboot/boot_utils.c +++ b/jni/magiskboot/boot_utils.c @@ -8,7 +8,7 @@ void mmap_ro(const char *filename, void **buf, size_t *size) { int fd = xopen(filename, O_RDONLY); *size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - *buf = xmmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0); + *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0) : NULL; close(fd); } @@ -16,7 +16,7 @@ void mmap_rw(const char *filename, void **buf, size_t *size) { int fd = xopen(filename, O_RDWR); *size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - *buf = xmmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) : NULL; close(fd); } diff --git a/jni/magiskboot/bootimg.c b/jni/magiskboot/bootimg.c index 37f5f3c26..138384236 100644 --- a/jni/magiskboot/bootimg.c +++ b/jni/magiskboot/bootimg.c @@ -30,7 +30,7 @@ static void print_hdr(const boot_img_hdr *hdr) { fprintf(stderr, "KERNEL [%d] @ 0x%08x\n", hdr->kernel_size, hdr->kernel_addr); fprintf(stderr, "RAMDISK [%d] @ 0x%08x\n", hdr->ramdisk_size, hdr->ramdisk_addr); fprintf(stderr, "SECOND [%d] @ 0x%08x\n", hdr->second_size, hdr->second_addr); - fprintf(stderr, "DTB [%d] @ 0x%08x\n", hdr->dt_size, hdr->tags_addr); + fprintf(stderr, "EXTRA [%d] @ 0x%08x\n", hdr->extra_size, hdr->tags_addr); fprintf(stderr, "PAGESIZE [%d]\n", hdr->page_size); if (hdr->os_version != 0) { int a,b,c,y,m = 0; @@ -88,26 +88,24 @@ int parse_img(void *orig, size_t size, boot_img *boot) { mem_align(&pos, boot->hdr.page_size); } - if (boot->hdr.dt_size) { - boot->dtb = base + pos; - pos += boot->hdr.dt_size; + if (boot->hdr.extra_size) { + boot->extra = base + pos; + pos += boot->hdr.extra_size; mem_align(&pos, boot->hdr.page_size); } if (pos < size) { - boot->extra = base + pos; + boot->tail = base + pos; + boot->tail_size = end - base - pos; } - // Search for dtb in kernel if not found - if (boot->hdr.dt_size == 0) { - for (int i = 0; i < boot->hdr.kernel_size; ++i) { - if (memcmp(boot->kernel + i, DTB_MAGIC, 4) == 0) { - boot->flags |= APPEND_DTB; - boot->dtb = boot->kernel + i; - boot->hdr.dt_size = boot->hdr.kernel_size - i; - boot->hdr.kernel_size = i; - fprintf(stderr, "APPEND_DTB [%d]\n", boot->hdr.dt_size); - } + // Search for dtb in kernel + for (int i = 0; i < boot->hdr.kernel_size; ++i) { + if (memcmp(boot->kernel + i, DTB_MAGIC, 4) == 0) { + boot->dtb = boot->kernel + i; + boot->dt_size = boot->hdr.kernel_size - i; + boot->hdr.kernel_size = i; + fprintf(stderr, "DTB [%d]\n", boot->dt_size); } } @@ -146,6 +144,7 @@ int parse_img(void *orig, size_t size, boot_img *boot) { } } LOGE("No boot image magic found!\n"); + return 1; } void unpack(const char* image) { @@ -160,22 +159,27 @@ void unpack(const char* image) { int ret = parse_img(orig, size, &boot); // Dump kernel - if (boot.kernel_type == UNKNOWN) { - dump(boot.kernel, boot.hdr.kernel_size, KERNEL_FILE); - } else { + if (COMPRESSED(boot.kernel_type)) { fd = open_new(KERNEL_FILE); decomp(boot.kernel_type, fd, boot.kernel, boot.hdr.kernel_size); close(fd); + } else { + dump(boot.kernel, boot.hdr.kernel_size, KERNEL_FILE); + } + + if (boot.dt_size) { + // Dump dtb + dump(boot.dtb, boot.dt_size, DTB_FILE); } // Dump ramdisk - if (boot.ramdisk_type == UNKNOWN) { - dump(boot.ramdisk, boot.hdr.ramdisk_size, RAMDISK_FILE ".raw"); - LOGE("Unknown ramdisk format! Dumped to %s\n", RAMDISK_FILE ".raw"); - } else { + if (COMPRESSED(boot.ramdisk_type)) { fd = open_new(RAMDISK_FILE); decomp(boot.ramdisk_type, fd, boot.ramdisk, boot.hdr.ramdisk_size); close(fd); + } else { + dump(boot.ramdisk, boot.hdr.ramdisk_size, RAMDISK_FILE ".raw"); + LOGE("Unknown ramdisk format! Dumped to %s\n", RAMDISK_FILE ".raw"); } if (boot.hdr.second_size) { @@ -183,9 +187,9 @@ void unpack(const char* image) { dump(boot.second, boot.hdr.second_size, SECOND_FILE); } - if (boot.hdr.dt_size) { - // Dump dtb - dump(boot.dtb, boot.hdr.dt_size, DTB_FILE); + if (boot.hdr.extra_size) { + // Dump extra + dump(boot.extra, boot.hdr.extra_size, EXTRA_FILE); } munmap(orig, size); @@ -220,18 +224,18 @@ void repack(const char* orig_image, const char* out_image) { mtk_kernel_off = lseek(fd, 0, SEEK_CUR); write_zero(fd, 512); } - if (boot.kernel_type == UNKNOWN) { - boot.hdr.kernel_size = restore(KERNEL_FILE, fd); - } else { + if (COMPRESSED(boot.kernel_type)) { size_t raw_size; void *kernel_raw; mmap_ro(KERNEL_FILE, &kernel_raw, &raw_size); boot.hdr.kernel_size = comp(boot.kernel_type, fd, kernel_raw, raw_size); munmap(kernel_raw, raw_size); + } else { + boot.hdr.kernel_size = restore(KERNEL_FILE, fd); } - if (boot.flags & APPEND_DTB) { + // Restore dtb + if (boot.dt_size && access(DTB_FILE, R_OK) == 0) { boot.hdr.kernel_size += restore(DTB_FILE, fd); - boot.hdr.dt_size = 0; } file_align(fd, boot.hdr.page_size, 1); @@ -270,18 +274,17 @@ void repack(const char* orig_image, const char* out_image) { file_align(fd, boot.hdr.page_size, 1); } - // Restore dtb - if (boot.hdr.dt_size && access(DTB_FILE, R_OK) == 0) { - printf("Here\n"); - boot.hdr.dt_size = restore(DTB_FILE, fd); + // Restore extra + if (boot.hdr.extra_size && access(EXTRA_FILE, R_OK) == 0) { + boot.hdr.extra_size = restore(EXTRA_FILE, fd); file_align(fd, boot.hdr.page_size, 1); } - // Check extra info, currently only for LG Bump and Samsung SEANDROIDENFORCE - if (boot.extra) { - if (memcmp(boot.extra, "SEANDROIDENFORCE", 16) == 0 || - memcmp(boot.extra, LG_BUMP_MAGIC, 16) == 0 ) { - restore_buf(fd, boot.extra, 16); + // Check tail info, currently only for LG Bump and Samsung SEANDROIDENFORCE + if (boot.tail_size >= 16) { + if (memcmp(boot.tail, "SEANDROIDENFORCE", 16) == 0 || + memcmp(boot.tail, LG_BUMP_MAGIC, 16) == 0 ) { + restore_buf(fd, boot.tail, 16); } } diff --git a/jni/magiskboot/bootimg.h b/jni/magiskboot/bootimg.h index 2c412d2c6..c27aa8c9d 100644 --- a/jni/magiskboot/bootimg.h +++ b/jni/magiskboot/bootimg.h @@ -44,7 +44,7 @@ struct boot_img_hdr uint32_t tags_addr; /* physical addr for kernel tags */ uint32_t page_size; /* flash page size we assume */ - uint32_t dt_size; /* device tree in bytes */ + uint32_t extra_size; /* extra blob size in bytes */ /* operating system version and security patch level; for * version "A.B.C" and patch level "Y-M-D": @@ -74,13 +74,13 @@ struct boot_img_hdr ** +-----------------+ ** | second stage | o pages ** +-----------------+ -** | device tree | p pages +** | extra blobs | p 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 = (dt_size + page_size - 1) / page_size +** p = (extra_size + page_size - 1) / page_size ** ** 0. all entities are page_size aligned in flash ** 1. kernel and ramdisk are required (size != 0) @@ -103,16 +103,18 @@ typedef struct mtk_hdr { // Flags #define MTK_KERNEL 0x1 #define MTK_RAMDISK 0x2 -#define APPEND_DTB 0x4 typedef struct boot_img { boot_img_hdr hdr; void *kernel; + void *dtb; + uint32_t dt_size; void *ramdisk; void *second; - void *dtb; void *extra; - int flags; + void *tail; + uint32_t tail_size; + uint32_t flags; file_t kernel_type, ramdisk_type; mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr; } boot_img; diff --git a/jni/magiskboot/dtb.c b/jni/magiskboot/dtb.c index a5904fb65..2251c6b3c 100644 --- a/jni/magiskboot/dtb.c +++ b/jni/magiskboot/dtb.c @@ -5,16 +5,14 @@ #include "magiskboot.h" #include "utils.h" -/* Left here for debugging */ - -// static void print_subnode(const void *fdt, int parent, int depth) { -// int node; -// fdt_for_each_subnode(node, fdt, parent) { -// for (int i = 0; i < depth; ++i) printf(" "); -// printf("%d: %s\n", node, fdt_get_name(fdt, node, NULL)); -// print_subnode(fdt, node, depth + 1); -// } -// } +static void print_subnode(const void *fdt, int parent, int depth) { + int node; + fdt_for_each_subnode(node, fdt, parent) { + for (int i = 0; i < depth; ++i) printf(" "); + printf("%d: %s\n", node, fdt_get_name(fdt, node, NULL)); + print_subnode(fdt, node, depth + 1); + } +} static int find_fstab(const void *fdt, int parent) { int node, fstab; @@ -28,6 +26,25 @@ static int find_fstab(const void *fdt, int parent) { return -1; } +void dtb_print(const char *file) { + size_t size ; + void *dtb, *fdt; + fprintf(stderr, "Loading dtbs from [%s]\n", file); + mmap_ro(file, &dtb, &size); + // Loop through all the dtbs + int dtb_num = 0; + for (int i = 0; i < size; ++i) { + if (memcmp(dtb + i, DTB_MAGIC, 4) == 0) { + fdt = dtb + i; + fprintf(stderr, "\nPrinting dtb.%04d\n\n", dtb_num++); + print_subnode(fdt, 0, 0); + } + } + fprintf(stderr, "\n"); + munmap(dtb, size); + exit(0); +} + void dtb_patch(const char *file) { size_t size ; void *dtb, *fdt; diff --git a/jni/magiskboot/hexpatch.c b/jni/magiskboot/hexpatch.c index cf5aa0e19..8fb3ad399 100644 --- a/jni/magiskboot/hexpatch.c +++ b/jni/magiskboot/hexpatch.c @@ -24,7 +24,7 @@ void hexpatch(const char *image, const char *from, const char *to) { patch = xmalloc(patchsize); hex2byte(from, pattern); hex2byte(to, patch); - for (size_t i = 0; i < filesize - patternsize; ++i) { + for (size_t i = 0; filesize > 0 && i < filesize - patternsize; ++i) { if (memcmp(file + i, pattern, patternsize) == 0) { fprintf(stderr, "Pattern %s found!\nPatching to %s\n", from, to); memset(file + i, 0, patternsize); diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index 74be6a73c..f13409850 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -8,6 +8,7 @@ #define KERNEL_FILE "kernel" #define RAMDISK_FILE "ramdisk.cpio" #define SECOND_FILE "second" +#define EXTRA_FILE "extra" #define DTB_FILE "dtb" #define NEW_BOOT "new-boot.img" @@ -22,6 +23,7 @@ int parse_img(void *orig, size_t size, boot_img *boot); int cpio_commands(const char *command, int argc, char *argv[]); void comp_file(const char *method, const char *from, const char *to); void decomp_file(char *from, const char *to); +void dtb_print(const char *file); void dtb_patch(const char *file); // Compressions diff --git a/jni/magiskboot/main.c b/jni/magiskboot/main.c index cf810b82d..5e138f8d7 100644 --- a/jni/magiskboot/main.c +++ b/jni/magiskboot/main.c @@ -54,6 +54,9 @@ static void usage(char *arg0) { " -stocksha1\n" " Get stock boot SHA1 recorded within \n" "\n" + " --dtb-print \n" + " Print all nodes in , for debugging\n" + "\n" " --dtb-patch \n" " Search for fstab in and remove verity checks\n" "\n" @@ -94,6 +97,7 @@ int main(int argc, char *argv[]) { unlink(RAMDISK_FILE ".raw"); unlink(SECOND_FILE); unlink(DTB_FILE); + unlink(EXTRA_FILE); for (int i = 0; SUP_EXT_LIST[i]; ++i) { sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]); unlink(name); @@ -113,6 +117,8 @@ int main(int argc, char *argv[]) { repack(argv[2], argc > 3 ? argv[3] : NEW_BOOT); } else if (argc > 2 && strcmp(argv[1], "--decompress") == 0) { decomp_file(argv[2], argc > 3 ? argv[3] : NULL); + } else if (argc > 2 && strcmp(argv[1], "--dtb-print") == 0) { + dtb_print(argv[2]); } else if (argc > 2 && strcmp(argv[1], "--dtb-patch") == 0) { dtb_patch(argv[2]); } else if (argc > 2 && strncmp(argv[1], "--compress", 10) == 0) { diff --git a/jni/magiskboot/types.h b/jni/magiskboot/types.h index e4c851825..5a2bd37a1 100644 --- a/jni/magiskboot/types.h +++ b/jni/magiskboot/types.h @@ -18,6 +18,8 @@ typedef enum { DTB } file_t; +#define COMPRESSED(type) (type >= GZIP && type <= LZ4_LEGACY) + #define CHROMEOS_MAGIC "CHROMEOS" #define ELF32_MAGIC "\x7f""ELF\x01" #define ELF64_MAGIC "\x7f""ELF\x02" diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index dafe73d14..da6d81c32 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -66,17 +66,6 @@ cpio_mkdir() { # Initialization ########################################################################################## -BOOTIMAGE="$1" - -[ -e "$BOOTIMAGE" ] || (echo "$BOOTIMAGE does not exist!" && exit 1) - -# Presets -[ -z $KEEPVERITY ] && KEEPVERITY=false -[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false - -# Detect whether running as root -id | grep "uid=0" >/dev/null 2>&1 && ROOT=true || ROOT=false - if [ -z $SOURCEDMODE ]; then # Switch to the location of the script file cd "`dirname_wrap "${BASH_SOURCE:-$0}"`" @@ -86,6 +75,14 @@ if [ -z $SOURCEDMODE ]; then mount_partitions fi +BOOTIMAGE="$1" + +[ -e "$BOOTIMAGE" ] || abort "$BOOTIMAGE does not exist!" + +# Presets +[ -z $KEEPVERITY ] && KEEPVERITY=false +[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false + chmod -R 755 . ########################################################################################## @@ -104,6 +101,7 @@ case $? in abort "! Unable to unpack boot image" ;; 2 ) + ui_print "- ChromeOS boot image detected" CHROMEOS=true ;; 3 ) @@ -145,7 +143,7 @@ case $? in # Restore failed ui_print "! Cannot restore from internal backup" # If we are root and SHA1 known, we try to find the stock backup - if $ROOT && [ ! -z $SHA1 ]; then + if [ ! -z $SHA1 ]; then STOCKDUMP=/data/stock_boot_${SHA1}.img if [ -f ${STOCKDUMP}.gz ]; then ui_print "- Stock boot image backup found" diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index 0fb98226e..0b5770911 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -32,12 +32,7 @@ get_outfd() { } ui_print() { - if $BOOTMODE; then - echo "$1" - else - echo -n -e "ui_print $1\n" >> /proc/self/fd/$OUTFD - echo -n -e "ui_print\n" >> /proc/self/fd/$OUTFD - fi + $BOOTMODE && echo "$1" || echo -e "ui_print $1\nui_print" >> /proc/self/fd/$OUTFD } mount_partitions() { @@ -155,8 +150,9 @@ flash_boot_image() { } sign_chromeos() { - echo > empty + ui_print "- Signing ChromeOS boot image" + echo > empty ./chromeos/futility vbutil_kernel --pack new-boot.img.signed \ --keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \ --version 1 --vmlinuz new-boot.img --config empty --arch arm --bootloader empty --flags 0x1