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 slotUSB1_PATH–"/mnt/usb1/"– Mount point for the second USB slotUSB_PATH–"/mnt/usb%d/"– Template string used withsprintf()to generate paths for any slot 0-7FAKE_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-0SAVES_PATH_USB1–USB1_PATH PS4_SAVES_PATH_USB– Full path to PS4 saves on USB-1TROPHY_PATH_USB0–USB0_PATH TROPHIES_PATH_USB– Trophy exports on USB-0TROPHY_PATH_USB1–USB1_PATH TROPHIES_PATH_USB– Trophy exports on USB-1EXPORT_PATH_USB0–USB0_PATH "PS4/EXPORT/"– General export folder on USB-0EXPORT_PATH_USB1–USB1_PATH "PS4/EXPORT/"– General export folder on USB-1IMP_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 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 usingFAKE_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:
- Iterates through USB slots 0-7
- Creates a temporary file named
.apolloin each mount point - If the file opens successfully for writing, the slot is considered writable
- Removes the temporary file and strips the
.apolloextension from the path - Returns the first writable USB path found
- 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.hand 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_pathfunction insource/main.chandles USB selection through three modes: explicit slot selection, fake USB fallback, and auto-detection. - Auto-detection works by attempting to write a temporary
.apollofile to each USB slot (0-7) and selecting the first writable mount point, falling back toFAKE_USB_PATHif 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →