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

> Master the Apollo PS4 save mounting process. Learn about APOLLO_SANDBOX_PATH and crucial mount flags to effectively manage your PS4 game saves.

- Repository: [Damián Parrino/apollo-ps4](https://github.com/bucanero/apollo-ps4)
- Tags: deep-dive
- Published: 2026-02-26

---

**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`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) and [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) (line 6), the sandbox path is defined as:

```c
#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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c) within the `mountSave()` function (lines 93-106). After decrypting the sealed key via `decryptSealedKeyAtPath()`, Apollo calls the PlayStation 4 kernel API:

```c
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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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)

```c
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`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) (lines 74-106) and the sandbox path defined in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h).

### Mount a Trophy Set (Read-Only)

```c
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`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) handles path resolution for trophy sets.

### Safely Unmount and Clean Up

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

```

Implemented in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) (lines 57-71) and [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c) (`umountSave`, lines 12-18).

## Key Implementation Files

| File | Purpose |
|------|---------|
| **[`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h)** | Defines `APOLLO_SANDBOX_PATH`, save-type flags (`SAVE_FLAG_*`), and public API prototypes. |
| **[`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c)** | High-level orchestration including `orbis_SaveMount` (lines 74-106) and `orbis_SaveUmount` (lines 57-71). |
| **[`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c)** | Low-level wrappers `mountSave` and `umountSave` that invoke `sceFsMountSaveData` and `sceFsUmountSaveData`. |
| **[`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c)** | Demonstrates practical flag combination for mounting Apollo’s own configuration saves. |
| **[`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c), lines 12-18) completes and `orbis_SaveUmount` (in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c), lines 57-71) returns success, the directory is deleted to restore the filesystem to its pre-mount state.