diff --git a/native/src/init/twostage.cpp b/native/src/init/twostage.cpp
index 50fc348ac..41ebbef3f 100644
--- a/native/src/init/twostage.cpp
+++ b/native/src/init/twostage.cpp
@@ -10,11 +10,37 @@ using namespace std;
 
 void FirstStageInit::prepare() {
     prepare_data();
-    restore_ramdisk_init();
-    auto init = mmap_data("/init", true);
-    // Redirect original init to magiskinit
-    for (size_t off : init.patch(INIT_PATH, REDIR_PATH)) {
-        LOGD("Patch @ %08zX [" INIT_PATH "] -> [" REDIR_PATH "]\n", off);
+
+    if (struct stat st{}; fstatat(-1, "/sdcard", &st, AT_SYMLINK_NOFOLLOW) != 0 &&
+        fstatat(-1, "/first_stage_ramdisk/sdcard", &st, AT_SYMLINK_NOFOLLOW) != 0) {
+        if (config->force_normal_boot) {
+            xmkdirs("/first_stage_ramdisk/storage/self", 0755);
+            xsymlink("/system/system/bin/init", "/first_stage_ramdisk/storage/self/primary");
+            LOGD("Symlink /first_stage_ramdisk/storage/self/primary -> /system/system/bin/init\n");
+            close(xopen("/first_stage_ramdisk/sdcard", O_RDONLY | O_CREAT | O_CLOEXEC, 0));
+        } else {
+            xmkdirs("/storage/self", 0755);
+            xsymlink("/system/system/bin/init", "/storage/self/primary");
+            LOGD("Symlink /storage/self/primary -> /system/system/bin/init\n");
+        }
+        xrename("/init", "/sdcard");
+        // Try to keep magiskinit in rootfs for samsung RKP
+        if (mount("/sdcard", "/sdcard", nullptr, MS_BIND, nullptr) == 0) {
+            LOGD("Bind mount /sdcard -> /sdcard\n");
+        } else {
+            // rootfs before 3.12
+            xmount("/data/magiskinit", "/sdcard", nullptr, MS_BIND, nullptr);
+            LOGD("Bind mount /sdcard -> /data/magiskinit\n");
+        }
+        restore_ramdisk_init();
+    } else {
+        restore_ramdisk_init();
+        // fallback to hexpatch if /sdcard exists
+        auto init = mmap_data("/init", true);
+        // Redirect original init to magiskinit
+        for (size_t off : init.patch(INIT_PATH, REDIR_PATH)) {
+            LOGD("Patch @ %08zX [" INIT_PATH "] -> [" REDIR_PATH "]\n", off);
+        }
     }
 }
 
@@ -37,6 +63,7 @@ void LegacySARInit::first_stage_prep() {
 
 bool SecondStageInit::prepare() {
     umount2("/init", MNT_DETACH);
+    umount2(INIT_PATH, MNT_DETACH); // just in case
     unlink("/data/init");
 
     // Make sure init dmesg logs won't get messed up