Apollo PS4 Storage Path Definitions and USB Detection Handling

Apollo defines a family of path constants in include/saves.h to manage USB storage locations, and uses a write-test algorithm in 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

All storage-related macros are defined in 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_USB0USB0_PATH PS4_SAVES_PATH_USB – Full path to PS4 saves on USB-0
  • SAVES_PATH_USB1USB1_PATH PS4_SAVES_PATH_USB – Full path to PS4 saves on USB-1
  • TROPHY_PATH_USB0USB0_PATH TROPHIES_PATH_USB – Trophy exports on USB-0
  • TROPHY_PATH_USB1USB1_PATH TROPHIES_PATH_USB – Trophy exports on USB-1
  • EXPORT_PATH_USB0USB0_PATH "PS4/EXPORT/" – General export folder on USB-0
  • EXPORT_PATH_USB1USB1_PATH "PS4/EXPORT/" – General export folder on USB-1
  • IMP_PS2VMC_PATH_USBUSB_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 determines which storage location to use based on user configuration or automatic detection.

User Configuration Options

In source/settings.c, the USB source selection is defined as:

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:

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

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

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

Using the Fake USB Path for Debugging

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

Constructing Trophy Export Paths

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 Defines all storage path constants (USB0_PATH, FAKE_USB_PATH, SAVES_PATH_USB0, etc.) View on GitHub
source/main.c Implements update_usb_path() for USB detection and auto-selection logic View on GitHub
source/settings.c Contains the usb_src array defining user-selectable USB options View on GitHub
source/saves.c Uses path macros when reading/writing save files to USB devices View on GitHub
source/exec_cmd.c Demonstrates concatenation of FAKE_USB_PATH with subdirectories for command operations View on GitHub

Summary

  • Apollo PS4 storage path definitions are centralized in 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 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.

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.

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 →