diff --git a/native/jni/boot/bootimg.cpp b/native/jni/boot/bootimg.cpp index fce735a5d..e729c3f34 100644 --- a/native/jni/boot/bootimg.cpp +++ b/native/jni/boot/bootimg.cpp @@ -398,6 +398,13 @@ void boot_img::parse_image(uint8_t *addr, format_t type) { } fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]); } + if (!hdr->is_vendor && hdr->ramdisk_size() == 0 && hdr->header_version() == 4) { + // When a v4 boot image does not contain ramdisk, we will have to create + // the CPIO from scratch. However, since this ramdisk will have to be merged + // with other vendor ramdisks, it has to use the exact same compression method. + // v4 GKIs are required to use lz4 (legacy), so hardcode it here. + r_fmt = LZ4_LEGACY; + } if (auto size = hdr->extra_size()) { e_fmt = check_fmt_lg(extra, size); fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]); diff --git a/native/jni/init/twostage.cpp b/native/jni/init/twostage.cpp index 02b7c2e1f..03839bd46 100644 --- a/native/jni/init/twostage.cpp +++ b/native/jni/init/twostage.cpp @@ -17,7 +17,15 @@ void FirstStageInit::prepare() { cp_afc("/init" /* magiskinit */, REDIR_PATH); unlink("/init"); - xrename(backup_init(), "/init"); + const char *orig_init = backup_init(); + if (access(orig_init, F_OK) == 0) { + xrename(orig_init, "/init"); + } else { + // If the backup init is missing, this means that the boot ramdisk + // was created from scratch, and the real init is in a separate CPIO, + // which is guaranteed to be placed at /system/bin/init. + xsymlink(INIT_PATH, "/init"); + } { auto init = mmap_data("/init", true); diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 37a22477d..6f255eba4 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -111,7 +111,7 @@ if [ -e ramdisk.cpio ]; then ./magiskboot cpio ramdisk.cpio test STATUS=$? else - # Stock A only system-as-root + # Stock A only legacy SAR, or some Android 13 GKIs STATUS=0 fi case $((STATUS & 3)) in