Steam Frame microSD and USB: command reference
Tested 13–14 October 2026 on SteamOS 0.4.5, build 20261007.6125817.
Lepton launcher v3.0.5; Android image v3.0.3 (Android 11).

Choose one mode and follow its labelled commands for both Linux and the helper:
READ-ONLY: Linux --options ro; helper without an extra option.
READ/WRITE: Linux --options rw; helper with --read-write, enabling changes
and deletion on the actual drive. The helper defaults to read-only. If the
drive is already mounted in Linux, check its current access mode. If it
matches your chosen mode, keep it. Otherwise see CHANGING ACCESS MODE.
Guide URL: https://immernews.com/steam-frame-microsd-usb-storage
Helper download: https://immervr.de/files/Steam_Frame_microSD_USB_helper.zip
Python and the Linux tools run on the headset. No media is copied. The helper
does not install an automatic startup service or change OS runtime files.

ONE-TIME PREPARATION
Enable Steam Settings > System > Enable Developer Mode. Launch the standalone
version of immerGallery and keep it running. Use a USB data cable to the PC.
Extract Google's Platform Tools for your OS:
https://developer.android.com/tools/releases/platform-tools
Place map_lepton_storage.py in that platform-tools folder.

Windows: open Command Prompt in that folder; commands below use adb.
macOS / Linux: open Terminal in the folder; replace starting adb with ./adb.
Windows PowerShell: use .\adb.exe instead of adb, or use Command Prompt.
If ADB is already in PATH, adb is enough. No Python install on the PC is needed.

Each command is one logical line, even if your editor wraps it on screen.
Replace CARD_PATH, USB_PATH, USB_PARTITION and HEADSET_IP where indicated.

1. Connect and copy the helper (PC terminal)
adb devices -l
Expect frame with status device.
The examples use adb -d: USB only, with Steam Frame as the sole USB ADB device.
If other USB ADB devices are attached, disconnect them or replace -d with
-t TRANSPORT_ID, using the transport_id number from the native frame row.
Read it from adb devices -l; it can change after reconnecting. Do not choose
the frame:5555 or localhost:5555 row, which reaches Android/Lepton.
adb -d push map_lepton_storage.py /home/steamos/Documents/map_lepton_storage.py

2. Identify the microSD partition (PC terminal)
adb -d shell lsblk -p -o NAME,SIZE,FSTYPE,MOUNTPOINTS /dev/mmcblk0
The -p option prints full device paths. Check size and filesystem. The
remaining SD commands assume /dev/mmcblk0p1.
This is the tested layout, not a command to format or repartition a card.

3. Check whether Linux already mounted the card (PC terminal)
adb -d shell findmnt -rn -S /dev/mmcblk0p1 -o TARGET,OPTIONS
If a line appears, its first column is CARD_PATH, followed by options with
ro (read-only) or rw (read/write). If it matches your choice, skip the next
mount alternatives. If the mode differs, see CHANGING ACCESS MODE first.
No output means the card is not mounted. Only when unmounted, choose ONE:

READ-ONLY: mount in Linux for viewing:
adb -d shell udisksctl mount --block-device /dev/mmcblk0p1 --options ro --no-user-interaction
READ/WRITE: mount in Linux for viewing, saving and deleting:
adb -d shell udisksctl mount --block-device /dev/mmcblk0p1 --options rw --no-user-interaction

After mounting, run this again to confirm the folder and mode:
adb -d shell findmnt -rn -S /dev/mmcblk0p1 -o TARGET,OPTIONS
Use its first column, under /run/media/steamos, for CARD_PATH. It is the
folder containing your files, not the /dev/... partition path.
AlreadyMounted leaves the existing mode unchanged; it does not switch it.

4. Map the card (PC terminal)
Replace CARD_PATH with its actual Linux mount folder; keep the quotes.
Choose ONE command to match Linux. READ-ONLY source (ro):
adb -d shell "python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'CARD_PATH' --name microSD"
READ/WRITE source (rw), allowing writing and deletion:
adb -d shell "python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'CARD_PATH' --name microSD --read-write"
Put --read-write inside adb shell's outer double quotes, as shown.
Stop any playback in immerGallery, press the top-bar refresh icon, then
open microSD at the top level. Names are case-sensitive.

USB STICK, USING SSH TO FREE THE USB PORT
For USB-only use, do the preparation and step 1; skip steps 2 to 4.
You need the Linux steamos account password. Under Steam Settings > Developer,
Set User Password lets you choose a new one if none exists. Change User
Password means one already exists and requires the current password.
PC and headset need local-network connectivity.
Find the IP on Steam Frame under Quick Settings or Steam Settings > Internet,
then open the connected Wi-Fi network. Or, before unplugging USB, run on the PC:
adb -d shell ip -4 addr show wlan0
Use the address after inet, without its slash suffix, for HEADSET_IP:
ssh steamos@HEADSET_IP
SSH uses the headset's steamos account, already named in the command. The
password is the one set under Developer > Set User Password, not your Steam
account password. A password-free key setup is optional. Enter the password if
requested; no characters appear while typing. Confirm you are connecting to
your own headset when first accepting its SSH host key. Verify the connection
works before unplugging the USB cable and inserting the stick or adapter.
Windows Command Prompt can run ssh when the OpenSSH Client is installed and
available in PATH. Check first:
ssh -V
If a version appears, continue. Otherwise search Windows Settings for
Optional features, choose View features and install OpenSSH Client. Open
a new Command Prompt and try again. PuTTY is not needed for this guide.
https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?pivots=windows-11
Only the client is needed on the computer, not an SSH server.

Inside the Linux SSH session (no adb prefix):
lsblk -p -o NAME,SIZE,TRAN,FSTYPE,MOUNTPOINTS
The -p option shows full paths. Find the disk marked usb in TRAN and its
partition underneath, checking size and filesystem. The tree shows disk /
partition relationships, not folders. Linux's /dev contains device entries:
/dev/sdf is a whole disk; /dev/sdf1 is its first partition. The partition
is not /dev/sdf/sdf1 or sdf/sdf1. Use the actual full partition path for
USB_PARTITION; its name can change. Check its current mount:
findmnt -rn -S USB_PARTITION -o TARGET,OPTIONS
No output means it is not mounted. If already mounted in your chosen mode,
skip the mount alternatives. If the mode differs, see CHANGING ACCESS MODE.
Only for an unmounted partition, choose ONE:
READ-ONLY: mount in Linux for viewing:
udisksctl mount --block-device USB_PARTITION --options ro --no-user-interaction
READ/WRITE: mount in Linux for viewing, saving and deleting:
udisksctl mount --block-device USB_PARTITION --options rw --no-user-interaction

After mounting, run this again to confirm the folder and mode:
findmnt -rn -S USB_PARTITION -o TARGET,OPTIONS
The first column, normally /run/media/steamos/USB_ID, is USB_PATH.
Replace USB_PATH with that actual folder, keeping the quotes. Do not use
the partition's /dev/... path for the helper's --source.
READ-ONLY: share an ro source:
python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'USB_PATH' --name USBStick
READ/WRITE: share an rw source, allowing writing and deletion:
python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'USB_PATH' --name USBStick --read-write
Stop any playback in immerGallery, press the top-bar refresh icon, then
open USBStick.
AlreadyMounted does not change the access mode. If lsblk shows no USB disk,
check the physical connection first.

CHANGING ACCESS MODE
If the Linux mount already matches your choice, reuse it. To switch ro to
rw or rw to ro: close files, remove any existing app mapping using its
original access option plus --undo, then unmount the Linux source. Complete
commands for both drives and modes are in the removal section below.
If there is no app mapping yet, only unmount the Linux source. Stop if busy.
Then use the desired mode's mount command above, repeat findmnt, and run
its matching helper command. The helper does not change host permissions.
Alternatively, finish file operations, use the normal SteamOS Restart menu,
then reconnect and set up the drive in the desired mode. A normal restart
handles filesystem cleanup; keep the drive connected during it. A forced
reset or power loss is different. Unmount before unplugging while powered on.

AFTER A REBOOT OR LEPTON CONTAINER RESTART
Launch immerGallery, ensure the source drive is mounted with your chosen
access mode, then run the matching helper command. The script stays on the headset.
An empty folder may remain, but refresh does not recreate a missing mount.
The same helper command is harmless if the correct mount is already active.

REMOVE THE MAPPING BEFORE UNPLUGGING
Close media using the drive. Replace the same placeholders as when mounting.
For microSD, from the PC over native USB ADB:
adb -d shell "python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'CARD_PATH' --name microSD --undo"
adb -d shell udisksctl unmount --block-device /dev/mmcblk0p1 --no-user-interaction
For USBStick, inside the Linux SSH session:
python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'USB_PATH' --name USBStick --undo
udisksctl unmount --block-device USB_PARTITION --no-user-interaction
If using a writable mapping, use the matching undo command instead:
microSD, PC terminal:
adb -d shell "python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'CARD_PATH' --name microSD --read-write --undo"
adb -d shell udisksctl unmount --block-device /dev/mmcblk0p1 --no-user-interaction
USBStick, inside Linux SSH:
python3 /home/steamos/Documents/map_lepton_storage.py --container lepton-steamlaunch-3073280 --source 'USB_PATH' --name USBStick --read-write --undo
udisksctl unmount --block-device USB_PARTITION --no-user-interaction
Do not continue to remove a drive if an unmount reports busy. Undo checks the
specified source; it will refuse a different drive. An empty folder may remain.

OTHER CHECKS (PC, native USB ADB)
Read the OS version and build:
adb -d shell cat /etc/os-release
List running containers if the helper cannot find immerGallery:
adb -d shell podman ps --format "{{.Names}}"
The tested container is lepton-steamlaunch-3073280. Each separately
Steam-launched Android app has its own container. Keep immerGallery running
for this mount. Native USB ADB still targets Linux, not the Android instance.

ADB CONNECTION ERRORS
"more than one device with serial frame": -s frame can match both the USB
frame connection and the TCP connection frame:5555. Use adb -d as above,
or choose the native connection explicitly with -t TRANSPORT_ID.

"/system/bin/sh: python3: inaccessible or not found": the command went to
Android/Lepton. The helper must run in SteamOS. Verify native USB access:
adb -d shell python3 --version
Then use the same selector for the helper. An rw source still requires
--read-write inside the outer double quotes of the adb shell command.

SCOPE
Read access tested: exFAT microSD and FAT32 USB (Linux driver name: vfat).
Read/write file operations verified on exFAT microSD and FAT32 USB.
immerGallery's Delete button also verified on both drives, with Linux confirming removal.
Mappings are temporary; choose read-only or explicitly enable read/write.
The native USB ADB target frame is Linux. Wi-Fi ADB on port 5555 is Lepton;
it is not a replacement for Linux SSH in the USB-stick steps.
Storage mounting needs no sudo or Android rooting and does not disable
OS read-only mode.

Official connection documentation:
https://partner.steamgames.com/doc/steamhardware/steamframe/setup
https://partner.steamgames.com/doc/steamhardware/steamframe/debugging
https://partner.steamgames.com/doc/steamhardware/steamframe/adb_lepton
https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/docs/user/adb.1.md
