# Apollo PS4 Storage Path Definitions and USB Detection Handling

> Learn Apollo PS4 storage path definitions like USB0_PATH and FAKE_USB_PATH. Discover how Apollo handles USB detection using a write-test algorithm.

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

---

**Apollo defines a family of path constants in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) to manage USB storage locations, and uses a write-test algorithm in [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) to auto-detect writable USB devices at runtime.**

The Apollo save tool for PlayStation 4 relies on specific **Apollo PS4 storage path definitions** to locate save data, trophies, and exports across multiple storage devices. These definitions are centralized in the `bucanero/apollo-ps4` repository and include both physical USB mount points and a fallback "fake" USB path for debugging scenarios.

## Storage Path Constants in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h)

All storage-related macros are defined in **[`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h)**. The file establishes base mount points for USB devices and then derives specific paths for saves, trophies, and virtual memory cards.

### Base USB Mount Points

Apollo supports up to eight physical USB slots (0-7) plus a fake USB location for development:

- **`USB0_PATH`** – `"/mnt/usb0/"` – Mount point for the first physical USB slot
- **`USB1_PATH`** – `"/mnt/usb1/"` – Mount point for the second USB slot  
- **`USB_PATH`** – `"/mnt/usb%d/"` – Template string used with `sprintf()` to generate paths for any slot 0-7
- **`FAKE_USB_PATH`** – `"/data/fakeusb/"` – Fallback directory used when physical USB devices are unavailable or read-only, useful for debugging without actual USB hardware

### Derived Content Paths

Apollo concatenates the base paths with subdirectories to create complete storage locations:

- **`SAVES_PATH_USB0`** – `USB0_PATH PS4_SAVES_PATH_USB` – Full path to PS4 saves on USB-0
- **`SAVES_PATH_USB1`** – `USB1_PATH PS4_SAVES_PATH_USB` – Full path to PS4 saves on USB-1
- **`TROPHY_PATH_USB0`** – `USB0_PATH TROPHIES_PATH_USB` – Trophy exports on USB-0
- **`TROPHY_PATH_USB1`** – `USB1_PATH TROPHIES_PATH_USB` – Trophy exports on USB-1
- **`EXPORT_PATH_USB0`** – `USB0_PATH "PS4/EXPORT/"` – General export folder on USB-0
- **`EXPORT_PATH_USB1`** – `USB1_PATH "PS4/EXPORT/"` – General export folder on USB-1
- **`IMP_PS2VMC_PATH_USB`** – `USB_PATH "PS2/VMC/"` – Path for importing PS2 Virtual Memory Cards from any USB slot

## USB Detection and Selection Logic

The **`update_usb_path`** function in [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) determines which storage location to use based on user configuration or automatic detection.

### User Configuration Options

In **[`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c)**, the USB source selection is defined as:

```c
static const char * usb_src[] = {
    "USB 0", "USB 1", "USB 2", "USB 3",
    "USB 4", "USB 5", "USB 6", "USB 7",
    _i18n("Fake USB"),
    _i18n("Auto-detect"),
    NULL };

```

- **Indices 0-7** – Explicit USB slot selection
- **Index 8** (`MAX_USB_DEVICES`) – **Fake USB** mode using `FAKE_USB_PATH`
- **Index 9** (`MAX_USB_DEVICES+1`) – **Auto-detect** mode

### The Auto-Detect Algorithm

When **Auto-detect** is selected, Apollo performs a write-test on each potential USB mount point:

```c
for (int i = 0; i < MAX_USB_DEVICES; i++) {
    sprintf(path, USB_PATH ".apollo", i);
    FILE *fp = fopen(path, "w");
    if (!fp) continue;
    fclose(fp);
    remove(path);
    *strrchr(path, '.') = 0;   // strip ".apollo"
    return;
}
sprintf(path, FAKE_USB_PATH);   // last resort

```

The algorithm:
1. Iterates through USB slots 0-7
2. Creates a temporary file named `.apollo` in each mount point
3. If the file opens successfully for writing, the slot is considered **writable**
4. Removes the temporary file and strips the `.apollo` extension from the path
5. Returns the first writable USB path found
6. If no USB devices are writable, falls back to `FAKE_USB_PATH` (if the directory exists) or clears the path

## Practical Code Examples

### Building Save Paths with the Active USB Device

```c
char usb_base[256];
update_usb_path(usb_base);  // Resolves to USB_PATH, FAKE_USB_PATH, or auto-detected slot

char saves_path[512];
snprintf(saves_path, sizeof(saves_path),
         "%s%s", usb_base, PS4_SAVES_PATH_USB);  // e.g., "/mnt/usb0/PS4/APOLLO/"

```

### Directly Accessing a Specific USB Slot

```c
char path[256];
sprintf(path, USB_PATH, 3);  // => "/mnt/usb3/"

```

### Using the Fake USB Path for Debugging

```c
char path[256];
sprintf(path, FAKE_USB_PATH);  // => "/data/fakeusb/"

```

### Constructing Trophy Export Paths

```c
char usb_path[256];
update_usb_path(usb_path);

char trophy_path[512];
snprintf(trophy_path, sizeof(trophy_path),
         "%s%s", usb_path, TROPHIES_PATH_USB);  // e.g., "/mnt/usb1/PS4/EXPORT/TROPHY/"

```

## Key Source Files

| File | Purpose | Location |
|------|---------|----------|
| [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) | Defines all storage path constants (`USB0_PATH`, `FAKE_USB_PATH`, `SAVES_PATH_USB0`, etc.) | [View on GitHub](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) |
| [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) | Implements `update_usb_path()` for USB detection and auto-selection logic | [View on GitHub](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) |
| [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) | Contains the `usb_src` array defining user-selectable USB options | [View on GitHub](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) |
| [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) | Uses path macros when reading/writing save files to USB devices | [View on GitHub](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) |
| [`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c) | Demonstrates concatenation of `FAKE_USB_PATH` with subdirectories for command operations | [View on GitHub](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c) |

## Summary

- **Apollo PS4 storage path definitions** are centralized in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) and include base mount points (`USB0_PATH`, `USB1_PATH`, `USB_PATH`, `FAKE_USB_PATH`) and derived content paths for saves, trophies, and exports.
- The **`update_usb_path`** function in [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) handles USB selection through three modes: explicit slot selection, fake USB fallback, and auto-detection.
- **Auto-detection** works by attempting to write a temporary `.apollo` file to each USB slot (0-7) and selecting the first writable mount point, falling back to `FAKE_USB_PATH` if necessary.
- The **`FAKE_USB_PATH`** (`/data/fakeusb/`) provides a debugging mechanism when physical USB devices are unavailable or read-only.

## Frequently Asked Questions

### What is the difference between USB0_PATH and FAKE_USB_PATH in Apollo?

**`USB0_PATH`** (`/mnt/usb0/`) represents the physical mount point for the first USB slot on the PS4, while **`FAKE_USB_PATH`** (`/data/fakeusb/`) is a fallback directory on the internal hard drive used for debugging or when no writable USB device is available. The fake path allows developers to test export functionality without physical USB hardware.

### How does Apollo automatically detect which USB port to use?

Apollo's **auto-detect** algorithm iterates through USB slots 0-7 and attempts to create a temporary file named `.apollo` in each mount point. The first slot that successfully opens the file for writing is selected as the active USB device. If no slots are writable, Apollo falls back to `FAKE_USB_PATH`. This logic is implemented in the `update_usb_path` function in [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c).

### Can Apollo access USB devices beyond USB0 and USB1?

Yes, Apollo supports up to **eight USB slots** (0-7) through the **`USB_PATH`** template macro (`/mnt/usb%d/`). While the UI explicitly lists USB 0 and USB 1 in the settings menu, the underlying code can format paths for any slot from 0 to 7 using `sprintf(path, USB_PATH, slot_number)`.

### What happens if no USB device is connected when using auto-detect mode?

If **auto-detect** is enabled and no USB device accepts write operations, Apollo attempts to use **`FAKE_USB_PATH`** (`/data/fakeusb/`) as a last resort. If the fake USB directory does not exist or is also unavailable, the path string is cleared, and operations requiring USB storage will fail or be skipped depending on the specific function implementation.