From 959b76d08a62354a526560ad7f8e35a440d17560 Mon Sep 17 00:00:00 2001 From: Vojtech Bocek Date: Thu, 26 Feb 2015 15:30:18 +0100 Subject: [PATCH] Move bootimg injecting to the lib, trampoline now has --inject=boot.img --- device_defines.mk | 12 + install_zip/Android.mk | 2 - .../prebuilt-installer/scripts/inject_boot.sh | 97 +------- lib/Android.mk | 4 +- lib/inject.c | 232 ++++++++++++++++++ lib/inject.h | 23 ++ lib/util.c | 5 + lib/util.h | 2 + multirom.c | 147 +---------- trampoline/Android.mk | 2 +- trampoline/trampoline.c | 24 ++ 11 files changed, 312 insertions(+), 238 deletions(-) create mode 100644 lib/inject.c create mode 100644 lib/inject.h diff --git a/device_defines.mk b/device_defines.mk index 80f8475..49014cc 100644 --- a/device_defines.mk +++ b/device_defines.mk @@ -109,3 +109,15 @@ ifeq ($(MR_CONTINUOUS_FB_UPDATE),true) endif LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) + +ifeq ($(MR_USE_MROM_FSTAB),true) + LOCAL_CFLAGS += -DMR_USE_MROM_FSTAB +endif + +ifeq ($(MR_ENCRYPTION),true) + LOCAL_CFLAGS += -DMR_ENCRYPTION +endif + +ifneq ($(MR_RD_ADDR),) + LOCAL_CFLAGS += -DMR_RD_ADDR=$(MR_RD_ADDR) +endif diff --git a/install_zip/Android.mk b/install_zip/Android.mk index 087cf0b..925e112 100644 --- a/install_zip/Android.mk +++ b/install_zip/Android.mk @@ -59,8 +59,6 @@ $(MULTIROM_ZIP_TARGET): multirom trampoline fw_mounter signapk bbootimg mrom_kex cp -a $(TARGET_OUT_OPTIONAL_EXECUTABLES)/bbootimg $(MULTIROM_INST_DIR)/scripts/ cp $(PWD)/$(MR_FSTAB) $(MULTIROM_INST_DIR)/multirom/mrom.fstab $(install_zip_path)/extract_boot_dev.sh $(PWD)/$(MR_FSTAB) $(MULTIROM_INST_DIR)/scripts/bootdev - echo $(MR_RD_ADDR) > $(MULTIROM_INST_DIR)/scripts/rd_addr - echo "$(MR_USE_MROM_FSTAB)" > $(MULTIROM_INST_DIR)/scripts/use_mrom_fstab $(install_zip_path)/make_updater_script.sh $(TARGET_DEVICE) $(MULTIROM_INST_DIR)/META-INF/com/google/android "Installing MultiROM for" rm -f $(MULTIROM_ZIP_TARGET).zip $(MULTIROM_ZIP_TARGET)-unsigned.zip cd $(MULTIROM_INST_DIR) && zip -qr ../$(notdir $@)-unsigned.zip * diff --git a/install_zip/prebuilt-installer/scripts/inject_boot.sh b/install_zip/prebuilt-installer/scripts/inject_boot.sh index 245d5d9..0d0be4a 100644 --- a/install_zip/prebuilt-installer/scripts/inject_boot.sh +++ b/install_zip/prebuilt-installer/scripts/inject_boot.sh @@ -1,105 +1,10 @@ #!/sbin/sh -BUSYBOX="/tmp/multirom/busybox" -LZ4="/tmp/multirom/lz4" BOOT_DEV="$(cat /tmp/bootdev)" -RD_ADDR="$(cat /tmp/rd_addr)" -USE_MROM_FSTAB="$(cat /tmp/use_mrom_fstab)" -CMPR_GZIP=0 -CMPR_LZ4=1 if [ ! -e "$BOOT_DEV" ]; then echo "BOOT_DEV \"$BOOT_DEV\" does not exist!" return 1 fi -dd if=$BOOT_DEV of=/tmp/boot.img -/tmp/bbootimg -x /tmp/boot.img /tmp/bootimg.cfg /tmp/zImage /tmp/initrd.img /tmp/second.img /tmp/dtb.img -if [ ! -f /tmp/zImage ] ; then - echo "Failed to extract boot.img" - return 1 -fi - -rm -r /tmp/boot -mkdir /tmp/boot - -cd /tmp/boot -rd_cmpr=-1 -magic=$($BUSYBOX hexdump -n 4 -v -e '/1 "%02X"' "../initrd.img") -case "$magic" in - 1F8B*) # GZIP - $BUSYBOX gzip -d -c "../initrd.img" | $BUSYBOX cpio -i - rd_cmpr=CMPR_GZIP; - ;; - 02214C18) # LZ4 - $LZ4 -d "../initrd.img" stdout | $BUSYBOX cpio -i - rd_cmpr=CMPR_LZ4; - ;; - *) - echo "invalid ramdisk magic $magic" - ;; -esac - -if [ rd_cmpr == -1 ] || [ ! -f /tmp/boot/init ] ; then - echo "Failed to extract ramdisk!" - return 1 -fi - -# copy trampoline -if [ ! -e /tmp/boot/main_init ] ; then - mv /tmp/boot/init /tmp/boot/main_init -fi -cp /tmp/multirom/trampoline /tmp/boot/init -chmod 750 /tmp/boot/init - -# create ueventd and watchdogd symlink -# older versions were changing these to ../main_init, we need to change it back -if [ -L /tmp/boot/sbin/ueventd ] ; then - ln -sf ../init /tmp/boot/sbin/ueventd -fi -if [ -L /tmp/boot/sbin/watchdogd ] ; then - ln -sf ../init /tmp/boot/sbin/watchdogd -fi - -# copy MultiROM's fstab if needed, remove old one if disabled -if [ "$USE_MROM_FSTAB" == "true" ]; then - echo "Using MultiROM's fstab" - cp /tmp/multirom/mrom.fstab /tmp/boot/mrom.fstab -elif [ -e /tmp/boot/mrom.fstab ] ; then - rm /tmp/boot/mrom.fstab -fi - -# pack the image again -cd /tmp/boot - -case $rd_cmpr in - CMPR_GZIP) - find . | $BUSYBOX cpio -o -H newc | $BUSYBOX gzip > "../initrd.img" - ;; - CMPR_LZ4) - find . | $BUSYBOX cpio -o -H newc | $LZ4 stdin "../initrd.img" - ;; -esac - -echo "bootsize = 0x0" >> /tmp/bootimg.cfg -if [ -n "$RD_ADDR" ]; then - echo "Using ramdisk addr $RD_ADDR" - echo "ramdiskaddr = $RD_ADDR" >> /tmp/bootimg.cfg -fi - -cd /tmp - -dtb_cmd="" -if [ -f "dtb.img" ]; then - dtb_cmd="-d dtb.img" -fi - -/tmp/bbootimg --create newboot.img -f bootimg.cfg -k zImage -r initrd.img $dtb_cmd - -if [ ! -e "/tmp/newboot.img" ] ; then - echo "Failed to inject boot.img!" - return 1 -fi - -echo "Writing new boot.img..." -dd bs=4096 if=/tmp/newboot.img of=$BOOT_DEV +/tmp/multirom/trampoline --inject="$BOOT_DEV" --mrom_dir="/tmp_multirom" -f return $? diff --git a/lib/Android.mk b/lib/Android.mk index 12260c7..1a705d9 100644 --- a/lib/Android.mk +++ b/lib/Android.mk @@ -10,6 +10,7 @@ common_SRC_FILES := \ framebuffer_png.c \ framebuffer_truetype.c \ fstab.c \ + inject.c \ input.c \ listview.c \ keyboard.c \ @@ -24,7 +25,8 @@ common_SRC_FILES := \ common_C_INCLUDES := $(multirom_local_path)/lib \ external/libpng \ external/zlib \ - external/freetype/include + external/freetype/include \ + system/extras/libbootimg/include \ # With these, GCC optimizes aggressively enough so full-screen alpha blending # is quick enough to be done in an animation diff --git a/lib/inject.c b/lib/inject.c new file mode 100644 index 0000000..2e4e8f2 --- /dev/null +++ b/lib/inject.c @@ -0,0 +1,232 @@ +/* + * This file is part of MultiROM. + * + * MultiROM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MultiROM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MultiROM. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "inject.h" +#include "mrom_data.h" +#include "log.h" +#include "util.h" +#include "../version.h" + +// clone libbootimg to /system/extras/ from +// https://github.com/Tasssadar/libbootimg.git +#include + +#if LIBBOOTIMG_VERSION < 0x000200 +#error "libbootimg version 0.2.0 or higher is required. Please update libbootimg." +#endif + +#define TMP_RD_UNPACKED_DIR "/mrom_rd" + +static int get_img_trampoline_ver(struct bootimg *img) +{ + int ver = 0; + if(strncmp((char*)img->hdr.name, "tr_ver", 6) == 0) + ver = atoi((char*)img->hdr.name + 6); + return ver; +} + +static int copy_rd_files(const char *path, const char *busybox_path) +{ + char buf[256]; + + if (access(TMP_RD_UNPACKED_DIR"/main_init", F_OK) < 0 && + rename(TMP_RD_UNPACKED_DIR"/init", TMP_RD_UNPACKED_DIR"/main_init") < 0) + { + ERROR("Failed to move /init to /main_init!"); + return -1; + } + + snprintf(buf, sizeof(buf), "%s/trampoline", mrom_dir()); + if(copy_file(buf, TMP_RD_UNPACKED_DIR"/init") < 0) + { + ERROR("Failed to copy trampoline to /init!"); + return -1; + } + chmod(TMP_RD_UNPACKED_DIR"/init", 0750); + +#ifdef MR_USE_MROM_FSTAB + snprintf(buf, "%s/mrom.fstab", mrom_dir()); + copy_file(buf, TMP_RD_UNPACKED_DIR"/mrom.fstab"); +#else + remove(TMP_RD_UNPACKED_DIR"/mrom.fstab"); +#endif + +#ifdef MR_ENCRYPTION + remove_dir(TMP_RD_UNPACKED_DIR"/mrom_enc"); + + char *cmd[] = { busybox_path, "sh", "-c", buf, NULL }; + snprintf(buf, sizeof(buf), "\"%s\" cp -a \"%s/enc\" \"%s/mrom_enc\"", busybox_path, mrom_dir(), TMP_RD_UNPACKED_DIR); + + if(run_cmd(cmd) != 0) + { + ERROR("Failed to copy encryption files!"); + return -1; + } +#endif + return 0; +} + +#define RD_GZIP 1 +#define RD_LZ4 2 +static int inject_rd(const char *path) +{ + int result = -1; + uint32_t magic = 0; + + FILE *f = fopen(path, "r"); + if(!f) + { + ERROR("Couldn't open %s!\n", path); + return -1; + } + fread(&magic, sizeof(magic), 1, f); + fclose(f); + + remove_dir(TMP_RD_UNPACKED_DIR); + mkdir(TMP_RD_UNPACKED_DIR, 0755); + + // Decompress initrd + int type; + char buff[256]; + char busybox_path[256]; + snprintf(busybox_path, sizeof(busybox_path), "%s/busybox", mrom_dir()); + + char *cmd[] = { busybox_path, "sh", "-c", buff, NULL }; + + if((magic & 0xFFFF) == 0x8B1F) + { + type = RD_GZIP; + snprintf(buff, sizeof(buff), "B=\"%s\"; cd \"%s\"; \"$B\" gzip -d -c \"%s\" | \"$B\" cpio -i", busybox_path, TMP_RD_UNPACKED_DIR, path); + } + else if(magic == 0x184C2102) + { + type = RD_LZ4; + snprintf(buff, sizeof(buff), "cd \"%s\"; \"%s/lz4\" -d \"%s\" stdout | \"%s\" cpio -i", TMP_RD_UNPACKED_DIR, mrom_dir(), path, busybox_path); + } + else + { + ERROR("Unknown ramdisk magic 0x%08X, can't update trampoline\n", magic); + goto success; + } + + int r = run_cmd(cmd); + if(r != 0) + { + ERROR("Failed to unpack ramdisk!\n"); + goto fail; + } + + // Update files + if(copy_rd_files(path, busybox_path) < 0) + goto fail; + + // Pack initrd again + switch(type) + { + case RD_GZIP: + snprintf(buff, sizeof(buff), "B=\"%s\"; cd \"%s\"; \"$B\" find . | \"$B\" cpio -o -H newc | \"$B\" gzip > \"%s\"", busybox_path, TMP_RD_UNPACKED_DIR, path); + break; + case RD_LZ4: + snprintf(buff, sizeof(buff), "B=\"%s\"; cd \"%s\"; \"$B\" find . | \"$B\" cpio -o -H newc | \"%s/lz4\" stdin \"%s\"", busybox_path, TMP_RD_UNPACKED_DIR, mrom_dir(), path); + break; + } + + r = run_cmd(cmd); + if(r != 0) + { + ERROR("Failed to pack ramdisk!\n"); + goto fail; + } + +success: + result = 0; +fail: + remove_dir(TMP_RD_UNPACKED_DIR); + return result; +} + +int inject_bootimg(const char *img_path, int force) +{ + int res = -1; + struct bootimg img; + int img_ver; + char initrd_path[256]; + static const char *initrd_tmp_name = "/inject-initrd.img"; + + if(libbootimg_init_load(&img, img_path, LIBBOOTIMG_LOAD_ALL) < 0) + { + ERROR("Could not open boot image (%s)!", img_path); + return -1; + } + + img_ver = get_img_trampoline_ver(&img); + if(!force && img_ver >= VERSION_TRAMPOLINE) + { + INFO("No need to update trampoline."); + res = 0; + goto exit; + } + + INFO("Updating trampoline from ver %d to %d", img_ver, VERSION_TRAMPOLINE); + + if(libbootimg_dump_ramdisk(&img, initrd_tmp_name) < 0) + { + ERROR("Failed to dump ramdisk to %s!", initrd_path); + goto exit; + } + + if(inject_rd(initrd_tmp_name) >= 0) + { + // Update the boot.img + snprintf((char*)img.hdr.name, BOOT_NAME_SIZE, "tr_ver%d", VERSION_TRAMPOLINE); +#ifdef MR_RD_ADDR + img.hdr.ramdisk_addr = MR_RD_ADDR; +#endif + + if(libbootimg_load_ramdisk(&img, initrd_tmp_name) < 0) + { + ERROR("Failed to load ramdisk from %s!", initrd_tmp_name); + goto exit; + } + + char tmp[256]; + strcpy(tmp, img_path); + strcat(tmp, ".new"); + if(libbootimg_write_img(&img, tmp) >= 0) + { + INFO("Writing boot.img updated with trampoline v%d\n", VERSION_TRAMPOLINE); + if(copy_file(tmp, img_path) < 0) + ERROR("Failed to copy %s to %s!", tmp, img_path); + else + res = 0; + remove(tmp); + } + else + ERROR("Failed to libbootimg_write_img!"); + } + +exit: + libbootimg_destroy(&img); + remove("/inject-initrd.img"); + return res; +} diff --git a/lib/inject.h b/lib/inject.h new file mode 100644 index 0000000..6b2f6c4 --- /dev/null +++ b/lib/inject.h @@ -0,0 +1,23 @@ +/* + * This file is part of MultiROM. + * + * MultiROM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MultiROM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MultiROM. If not, see . + */ + +#ifndef INJECT_H +#define INJECT_H + +int inject_bootimg(const char *img_path, int force); + +#endif diff --git a/lib/util.c b/lib/util.c index 3f516e0..37dc81a 100644 --- a/lib/util.c +++ b/lib/util.c @@ -633,6 +633,11 @@ char *strtoupper(const char *str) return res; } +int strstartswith(const char *haystack, const char *needle) +{ + return strncmp(haystack, needle, strlen(needle)) == 0; +} + int create_loop_device(const char *dev_path, const char *img_path, int loop_num, int loop_chmod) { int file_fd, device_fd, res = -1; diff --git a/lib/util.h b/lib/util.h index d1d16d6..18fd41d 100644 --- a/lib/util.h +++ b/lib/util.h @@ -33,6 +33,7 @@ int make_link(const char *oldpath, const char *newpath); void remove_link(const char *oldpath, const char *newpath); int wait_for_file(const char *filename, int timeout); int copy_file(const char *from, const char *to); +int copy_dir(const char *from, const char *to); int mkdir_with_perms(const char *path, mode_t mode, const char *owner, const char *group); int write_file(const char *path, const char *value); int remove_dir(const char *dir); @@ -55,5 +56,6 @@ inline int in_rect(int x, int y, int rx, int ry, int rw, int rh); inline void *mzalloc(size_t size); // alloc and fill with 0s char *strtoupper(const char *str); +int strstartswith(const char *haystack, const char *needle); #endif diff --git a/multirom.c b/multirom.c index 5b52c97..ad139f8 100644 --- a/multirom.c +++ b/multirom.c @@ -39,6 +39,7 @@ #include "lib/containers.h" #include "lib/framebuffer.h" +#include "lib/inject.h" #include "lib/input.h" #include "lib/log.h" #include "lib/util.h" @@ -1669,6 +1670,14 @@ int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom * char img_path[256]; sprintf(img_path, "%s/boot.img", rom->base_path); + // Trampolines in ROM boot images may get out of sync, so we need to check it and + // update if needed. I can't do that during ZIP installation because of USB drives. + if(inject_bootimg(img_path, 0) < 0) + { + ERROR("Failed to inject bootimg!"); + return -1; + } + struct bootimg img; if(libbootimg_init_load(&img, img_path, LIBBOOTIMG_LOAD_ALL) < 0) { @@ -1692,36 +1701,6 @@ int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom * kexec_add_arg(kexec, "--dtb"); #endif - // Trampolines in ROM boot images may get out of sync, so we need to check it and - // update if needed. I can't do that during ZIP installation because of USB drives. - // That header.name is added by recovery. - int ver = 0; - if(strncmp((char*)img.hdr.name, "tr_ver", 6) == 0) - ver = atoi((char*)img.hdr.name + 6); - - if(ver < multirom_get_trampoline_ver()) - { - if(multirom_update_rd_trampoline("/initrd.img") != 0) - goto exit; - else - { - // Update the boot.img - snprintf((char*)img.hdr.name, BOOT_NAME_SIZE, "tr_ver%d", multirom_get_trampoline_ver()); - - if(libbootimg_load_ramdisk(&img, "/initrd.img") >= 0) - { - char tmp[256]; - strcpy(tmp, img_path); - strcat(tmp, ".new"); - if(libbootimg_write_img(&img, tmp) >= 0) - { - INFO("Writing boot.img updated with trampoline v%d\n", multirom_get_trampoline_ver()); - rename(tmp, img_path); - } - } - } - } - char cmdline[1536]; strcpy(cmdline, "--command-line="); @@ -2524,114 +2503,6 @@ int multirom_run_scripts(const char *type, struct multirom_rom *rom) return 0; } -#define RD_GZIP 1 -#define RD_LZ4 2 -int multirom_update_rd_trampoline(const char *path) -{ - int result = -1; - uint32_t magic = 0; - - FILE *f = fopen(path, "r"); - if(!f) - { - ERROR("Couldn't open %s!\n", path); - return -1; - } - fread(&magic, sizeof(magic), 1, f); - fclose(f); - - remove_dir("/mrom_rd"); - mkdir("/mrom_rd", 0755); - - // Decompress initrd - int type; - char buff[256]; - char *cmd[] = { busybox_path, "sh", "-c", buff, NULL }; - - if((magic & 0xFFFF) == 0x8B1F) - { - type = RD_GZIP; - snprintf(buff, sizeof(buff), "B=\"%s\"; cd /mrom_rd; \"$B\" gzip -d -c \"%s\" | \"$B\" cpio -i", busybox_path, path); - } - else if(magic == 0x184C2102) - { - type = RD_LZ4; - snprintf(buff, sizeof(buff), "cd /mrom_rd; \"%s/lz4\" -d \"%s\" stdout | \"%s\" cpio -i", mrom_dir(), path, busybox_path); - } - else - { - ERROR("Unknown ramdisk magic 0x%08X, can't update trampoline\n", magic); - goto success; - } - - int r = run_cmd(cmd); - if(r != 0) - { - ERROR("Failed to unpack ramdisk!\n"); - goto fail; - } - - if(access("/mrom_rd/init", F_OK) < 0 || access("/mrom_rd/main_init", F_OK) < 0) - { - ERROR("This ramdisk is not injected, skipping\n"); - goto success; - } - - // Check version - char *cmd_t[] = { "/mrom_rd/init", "-v", NULL }; - char *res = run_get_stdout(cmd_t); - int ver = 0; - if(res) - { - ver = atoi(res); - free(res); - } - else - { - ERROR("Failed to run trampoline!\n"); - goto fail; - } - - if(ver >= multirom_get_trampoline_ver()) - { - INFO("No need to update trampoline for this rd\n"); - goto success; - } - - INFO("Updating trampoline in %s from ver %d to %d\n", path, ver, multirom_get_trampoline_ver()); - - if(copy_file("/init", "/mrom_rd/init") < 0) - { - ERROR("Failed to update trampoline\n"); - goto fail; - } - chmod("/mrom_rd/init", 0755); - - // Pack initrd again - switch(type) - { - case RD_GZIP: - snprintf(buff, sizeof(buff), "B=\"%s\"; cd /mrom_rd; \"$B\" find . | \"$B\" cpio -o -H newc | \"$B\" gzip > \"%s\"", busybox_path, path); - break; - case RD_LZ4: - snprintf(buff, sizeof(buff), "B=\"%s\"; cd /mrom_rd; \"$B\" find . | \"$B\" cpio -o -H newc | \"%s/lz4\" stdin \"%s\"", busybox_path, mrom_dir(), path); - break; - } - - r = run_cmd(cmd); - if(r != 0) - { - ERROR("Failed to pack ramdisk!\n"); - goto fail; - } - -success: - result = 0; -fail: - remove_dir("/mrom_rd"); - return result; -} - #define IC_TYPE_PREDEF 0 #define IC_TYPE_USER 1 #define USER_IC_PATH "../Android/data/com.tassadar.multirommgr/files" diff --git a/trampoline/Android.mk b/trampoline/Android.mk index cbbc8fd..e14c069 100644 --- a/trampoline/Android.mk +++ b/trampoline/Android.mk @@ -12,7 +12,7 @@ LOCAL_MODULE_TAGS := eng LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) -LOCAL_STATIC_LIBRARIES := libcutils libc libmultirom_static +LOCAL_STATIC_LIBRARIES := libcutils libc libmultirom_static libbootimg LOCAL_FORCE_STATIC_EXECUTABLE := true ifeq ($(MR_INIT_DEVICES),) diff --git a/trampoline/trampoline.c b/trampoline/trampoline.c index 58f5c55..b30a9da 100644 --- a/trampoline/trampoline.c +++ b/trampoline/trampoline.c @@ -29,6 +29,7 @@ #include "../lib/log.h" #include "../lib/util.h" #include "../lib/fstab.h" +#include "../lib/inject.h" #include "../version.h" #include "adb.h" #include "../hooks.h" @@ -240,6 +241,9 @@ int main(int argc, char *argv[]) int i, res; static char *const cmd[] = { "/init", NULL }; struct fstab *fstab = NULL; + char *inject_path = NULL; + char *mrom_dir = NULL; + int force_inject = 0; for(i = 1; i < argc; ++i) { @@ -249,6 +253,26 @@ int main(int argc, char *argv[]) fflush(stdout); return 0; } + else if(strstartswith(argv[i], "--inject=")) + inject_path = argv[i] + strlen("--inject="); + else if(strstartswith(argv[i], "--mrom_dir=")) + mrom_dir = argv[i] + strlen("--mrom_dir="); + else if(strcmp(argv[i], "-f") == 0) + force_inject = 1; + } + + if(inject_path) + { + if(!mrom_dir) + { + printf("--mrom_dir=[path to multirom's data dir] needs to be specified!\n"); + fflush(stdout); + return 1; + } + + mrom_set_dir(mrom_dir); + mrom_set_log_tag("trampoline_inject"); + return inject_bootimg(inject_path, force_inject); } umask(000);