How Magisk Handles System-as-Root (SAR) Devices: Legacy vs 2-Stage Init

Magisk handles system-as-root devices by detecting the SAR layout at boot time, remounting the system partition as the root filesystem, and employing either a legacy symlink strategy or a two-stage init patch to inject root access while preserving the original Android boot sequence.

Magisk, the open-source rooting solution maintained by topjohnwu, must navigate the complexities of modern Android devices that ship with system-as-root (SAR) partitions. On these devices, the traditional /system directory is mounted directly as /, creating a read-only root filesystem that requires specialized handling to maintain both root access and system integrity.

Detecting SAR Mode During Boot

The magiskinit binary—Magisk's patched first-stage init—determines whether the device uses SAR by examining the boot configuration and environment flags.

In native/src/init/init.rs, the initialization logic checks config.skip_initramfs to identify legacy SAR devices that ship without a separate initramfs. Additionally, the installation scripts in scripts/util_functions.sh set the SYSTEM_AS_ROOT environment flag for downstream logic:


# scripts/util_functions.sh

if [ "$SYSTEM_AS_ROOT" ]; then
    ui_print "- Device is system-as-root"
fi

If skip_initramfs is true, Magisk enters the legacy SAR flow. Otherwise, it proceeds with standard initramfs detection and determines at runtime whether the device employs a 2-stage init.

Legacy SAR Handling and Root Remounting

For legacy SAR devices, Magisk must reconstruct the boot environment by mounting the system partition as the root directory. The legacy_system_as_root function in native/src/init/init.rs orchestrates this process:

fn legacy_system_as_root(&mut self) {
    info!("Legacy SAR Init");
    self.prepare_data();
    let is_two_stage = self.mount_system_root();
    if is_two_stage {
        hexpatch_init_for_second_stage(false);
    } else {
        self.patch_ro_root();
    }
}

The mount_system_root() method mounts /system as /, effectively switching the root filesystem to the system partition. If the device uses a 2-stage init (is_two_stage == true), Magisk applies a binary patch via hexpatch_init_for_second_stage to redirect the second-stage execution. Otherwise, it calls patch_ro_root() to configure the root as read-only and continues booting.

After completing its setup, magiskinit restores the original init binary through restore_ramdisk_init():

fn restore_ramdisk_init(&self) {
    cstr!("/init").remove().ok();
    let orig_init = backup_init();
    if orig_init.exists() {
        orig_init.rename_to(cstr!("/init")).log_ok();
    } else {
        // Boot ramdisk created from scratch – fall back to /system/bin/init
        cstr!("/init")
            .create_symlink_to(cstr!("/system/bin/init"))
            .log_ok();
    }
}

This restoration either renames the backed-up original init or creates a symlink from /init to /system/bin/init when the ramdisk was generated from scratch.

Modern 2-Stage Init (2SI) SAR Support

Newer SAR devices utilize a 2-stage init process that requires a different injection strategy. According to the Magisk documentation in docs/details.md, the modern flow operates as follows:

  1. Early mount of required partitions (boot, vendor, system) before the standard init executes
  2. Binary patching of the original init to redirect the second-stage init file to magiskinit
  3. Execution of the patched flow, where magiskinit mounts the real /system as / and then invokes the original init as the second stage

This approach avoids the legacy remounting complexity by intercepting the init handoff rather than replacing the entire root filesystem structure.

Mutable Root Directory with overlay.d

Since SAR devices mount / as read-only, Magisk provides an overlay directory mechanism to enable runtime modifications. The overlay.d directory is bind-mounted over the root directory, allowing developers to replace files in rootdir or add new *.rc scripts without modifying the immutable system image.

As documented in docs/guides.md, this overlay system is essential for modules and developers who need to inject files into the root filesystem on devices where direct modification is impossible due to the read-only nature of system-as-root layouts.

Summary

  • SAR Detection: Magisk detects system-as-root devices via config.skip_initramfs in native/src/init/init.rs and the SYSTEM_AS_ROOT flag in scripts/util_functions.sh
  • Legacy Flow: On legacy SAR devices, mount_system_root() switches root to the system partition, followed by either hexpatch_init_for_second_stage() for 2-stage devices or patch_ro_root() for standard devices
  • 2SI Flow: Modern devices use binary patching to redirect the second-stage init execution while preserving the early mount process
  • Boot Restoration: The restore_ramdisk_init() function ensures the original init binary or symlink is restored before continuing the Android boot sequence
  • Overlay Support: The overlay.d bind-mount mechanism provides a mutable layer over the read-only root directory for file injection and script addition

Frequently Asked Questions

What is a system-as-root device?

A system-as-root device is an Android device where the system partition is mounted directly as the root filesystem (/) rather than being mounted at /system. This architecture became standard with Android 10 and dynamic partitions, creating a read-only root directory that requires specialized handling by rooting solutions like Magisk.

How does Magisk detect if a device uses SAR?

Magisk detects SAR during the early boot phase by checking the skip_initramfs configuration parameter in native/src/init/init.rs. If this flag is set, the device is classified as legacy SAR. Additionally, installation scripts set a SYSTEM_AS_ROOT environment variable in scripts/util_functions.sh to flag these devices during the installation process.

What is the difference between legacy SAR and 2-stage init handling?

Legacy SAR handling remounts the system partition as root using mount_system_root() and either patches the root to be read-only or applies hexpatch_init_for_second_stage if the device supports two-stage initialization. 2SI (2-Stage Init) handling patches the original init binary to redirect execution to magiskinit, which performs early mounts and then hands control to the original init as the second stage, avoiding the need for full root remounting.

How can developers modify files on SAR devices with Magisk?

Developers can use the overlay.d system, which Magisk bind-mounts over the read-only root directory. This allows replacement of files in rootdir and addition of new *.rc scripts without altering the immutable system image, providing a persistent mechanism for root-level modifications on system-as-root devices.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →