Understanding the Apollo PS4 Save Mounting Process: APOLLO_SANDBOX_PATH and Mount Flags Explained

Apollo mounts PS4 save data through a three-stage process: creating an isolated sandbox directory under APOLLO_SANDBOX_PATH, resolving the encrypted key and raw volume paths based on mount flags, and invoking the Orbis sceFsMountSaveData API with bitwise-combined access modes.

The bucanero/apollo-ps4 repository implements a sophisticated save mounting process that bridges user-level file operations with the PlayStation 4's kernel-level save data APIs. Understanding how Apollo handles APOLLO_SANDBOX_PATH and interprets different mount flags is essential for developers working with PS4 save data manipulation or homebrew tools.

The Three Stages of Save Mounting

Apollo’s save mounting process operates through distinct phases defined in source/saves.c and source/sd.c.

Stage 1: Sandbox Preparation with APOLLO_SANDBOX_PATH

Before invoking system calls, Apollo prepares a writable sandbox directory to isolate the mounted volume. In include/saves.h (line 6), the sandbox path is defined as:

#define APOLLO_SANDBOX_PATH   "/data/apollo/mount/%s/"

The %s placeholder is dynamically filled with the save’s directory name. The function orbis_SaveMount() in source/saves.c (lines 74-106) creates this directory using mkdirs() before mounting and removes it with rmdir() after unmounting. This sandbox prevents the mounted save from interfering with the rest of the filesystem and ensures clean teardown.

Stage 2: Key and Volume Path Resolution

Apollo builds the correct paths to the encrypted key and raw save volume based on the requested operation. In source/saves.c (lines 80-100), the code branches according to mount_mode flags:

  • SAVE_FLAG_TROPHY (line 87): Targets trophy sets using TROPHY_PATH_HDD paths (sealedkey and trophy.img).
  • SAVE_FLAG_LOCKED (line 92): Handles encrypted saves where the key lives alongside the raw data (%s%s.bin).
  • Default: Standard PS4 saves using SAVES_PATH_HDD paths (*.bin for keys, sdimg_* for volumes).

Stage 3: Orbis API Invocation

The actual mount operation occurs in source/sd.c within the mountSave() function (lines 93-106). After decrypting the sealed key via decryptSealedKeyAtPath(), Apollo calls the PlayStation 4 kernel API:

sceFsInitMountSaveDataOpt(&opt);
opt.budgetid = "system";
ret = sceFsMountSaveData(&opt, volumePath, mountPath, decryptedSealedKey);

The mountPath parameter points to the sandbox directory created in Stage 1, while volumePath and decryptedSealedKey come from Stage 2.

Understanding APOLLO_SANDBOX_PATH

The APOLLO_SANDBOX_PATH constant serves as the foundation for Apollo’s isolation strategy. By mounting saves into /data/apollo/mount/%s/ rather than system directories, Apollo achieves three critical objectives:

  1. Access Control: The sandbox directory is created with user-space permissions, avoiding permission conflicts with system processes.
  2. Clean Unmounting: After calling umountSave() in source/sd.c (lines 12-18), Apollo removes the empty directory with rmdir(), leaving no residual mount points.
  3. Conflict Prevention: Isolating each save in its own subdirectory prevents filename collisions when multiple saves are processed sequentially.

Mount Flags and Access Modes

Apollo uses bitwise flags to control mount behavior. These flags are passed to orbis_SaveMount() and ultimately to sceFsMountSaveData.

Orbis SDK Mount Modes

  • ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2: Creates a new save image if the key file does not exist (used in source/saves.c line 103).
  • ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: Opens the save for read-write access instead of read-only.
  • ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: Copies the save’s icon to the sandbox for UI display.

Apollo-Specific Flags

  • SAVE_FLAG_TROPHY: Redirects path resolution to trophy set locations (TROPHY_PATH_HDD).
  • SAVE_FLAG_LOCKED: Indicates the save uses external encryption keys alongside the volume.
  • SAVE_FLAG_PS4: Standard PS4 save type trigger for the mounting pipeline.
  • SAVE_FLAG_HDD: Indicates internal HDD storage (affects path construction).

These flags are combined using bitwise OR operations. For example, ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR creates a save if missing and opens it for writing.

Code Examples

Mount a Regular PS4 Save (Read-Write, Create if Missing)

save_entry_t *save = /* obtained from ReadUserList() */;
char mountPath[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];

if (orbis_SaveMount(save,
    ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 |
    ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
    ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON,
    mountPath)) {
    LOG("Mounted at %s", mountPath);
    /* operate on files under mountPath */
    orbis_SaveUmount(mountPath);
}

This example uses orbis_SaveMount from source/saves.c (lines 74-106) and the sandbox path defined in include/saves.h.

Mount a Trophy Set (Read-Only)

if (orbis_SaveMount(game, SAVE_FLAG_TROPHY, mountPath)) {
    // Trophy data accessible under mountPath
    // Uses TROPHY_PATH_HDD paths (sealedkey/trophy.img)
    orbis_SaveUmount(mountPath);
}

The SAVE_FLAG_TROPHY branch at line 87 in source/saves.c handles path resolution for trophy sets.

Safely Unmount and Clean Up

if (!orbis_SaveUmount(mountPath)) {
    LOG("Failed to unmount %s", mountPath);
} else {
    rmdir(mountPath); // Remove sandbox directory
}

Implemented in source/saves.c (lines 57-71) and source/sd.c (umountSave, lines 12-18).

Key Implementation Files

File Purpose
include/saves.h Defines APOLLO_SANDBOX_PATH, save-type flags (SAVE_FLAG_*), and public API prototypes.
source/saves.c High-level orchestration including orbis_SaveMount (lines 74-106) and orbis_SaveUmount (lines 57-71).
source/sd.c Low-level wrappers mountSave and umountSave that invoke sceFsMountSaveData and sceFsUmountSaveData.
source/settings.c Demonstrates practical flag combination for mounting Apollo’s own configuration saves.
source/exec_cmd.c Shows ad-hoc mounting for copy/export operations using the same pipeline.

These files collectively implement the complete mount pipeline: sandbox creation, path resolution, flag interpretation, and kernel API interaction.

Summary

  • Apollo isolates save data using APOLLO_SANDBOX_PATH (/data/apollo/mount/%s/) to create temporary mount points that prevent filesystem conflicts.
  • The mounting process involves three stages: sandbox preparation, key/volume path resolution based on flags, and invocation of sceFsMountSaveData via mountSave in source/sd.c.
  • Mount flags control behavior: ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 creates missing saves, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR enables writing, and Apollo-specific flags like SAVE_FLAG_TROPHY and SAVE_FLAG_LOCKED route to appropriate storage paths.
  • Cleanup is mandatory: After unmounting via orbis_SaveUmount, Apollo removes the sandbox directory with rmdir() to leave no residual mount points.

Frequently Asked Questions

What is APOLLO_SANDBOX_PATH used for?

APOLLO_SANDBOX_PATH is a format string defined in include/saves.h that specifies where Apollo creates temporary directories for mounting save data. By isolating each mount under /data/apollo/mount/%s/, Apollo prevents filesystem conflicts and ensures that read-write operations occur within a controlled environment that can be safely deleted after unmounting.

How does Apollo handle different types of save data?

Apollo uses bitwise flags to determine path resolution and mount behavior. When SAVE_FLAG_TROPHY is set, Apollo routes to TROPHY_PATH_HDD paths for trophy sets. The SAVE_FLAG_LOCKED flag indicates encrypted saves where the key file resides alongside the volume data. Standard PS4 saves use SAVES_PATH_HDD paths. These flags are evaluated in source/saves.c (lines 87-100) to construct the correct keyPath and volumePath before calling the mount API.

What is the difference between ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 and ORBIS_SAVE_DATA_MOUNT_MODE_RDWR?

ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 instructs the PlayStation 4 system to create a new save data image if the specified key file does not already exist, which Apollo uses when initializing new saves. ORBIS_SAVE_DATA_MOUNT_MODE_RDWR changes the access mode from read-only (default) to read-write, allowing Apollo to modify save contents. These flags are often combined using bitwise OR operations and passed to sceFsMountSaveData via the mountSave function in source/sd.c.

Why does Apollo delete the sandbox directory after unmounting?

Apollo removes the sandbox directory using rmdir() after successfully unmounting to ensure clean resource management and prevent accumulation of stale mount points. The sandbox directory at APOLLO_SANDBOX_PATH serves only as a temporary vessel for the mounted filesystem; once umountSave (in source/sd.c, lines 12-18) completes and orbis_SaveUmount (in source/saves.c, lines 57-71) returns success, the directory is deleted to restore the filesystem to its pre-mount state.

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 →