Steam Deck HowTo - Installing Pacman Packages In Userspace

Posted on September 17, 2022, updated on 2022-09-17 tags: steam-deck, linux, arch

I recently bought a Steam Deck with the intention of using it as a portable Linux machine as much as a game console. The Steam Deck has a read-only operating system root that is entirely replaced when the system is updated so executables can’t be installed normally with pacman. However, userspace is still persisted and executables can be installed there. Here’s how I set up a userspace root with pacman -r.

Background

Pacman is the package manager for Arch Linux which is the Linux distribution that the Steam Deck is built off of. Pacman supports an alternate installation root through the -r, --root <path> option that will be treated as the / filesystem point. The usual use for this is to perform package operations on other installations; for example, you might boot into a live USB to repair a broken installation and run pacman -r to repair packages. This is sort of like chroot just for pacman.

Prelude

Initialize User

If you haven’t yet, run passwd to set a password for the default user, deck, so that we can run sudo commands later.

SSH or Keyboard & Monitor

There’s going to be a lot of typing here. If you haven’t yet done so, I recommend setting up SSH or docking your Deck to a keyboard and monitor. If going the SSH route, I also suggest increasing the sleep timeout. Navigate to Plasma menu > System Settings > Power Management > Energy Saving. Then either uncheck “Suspend session” or set its timeout sufficiently high.

Process

1. Create a New Root

Somewhere in userspace, either your user directory /home/deck or a mounted SD card, create a folder that will be the new root at /home/deck/.root. I’ll call this $USERROOT and export it with export USERROOT=/home/deck/.root in .bashrc

2. Populate Keyring

Pacman uses a PGP keyring to sign and validate the integrity of packages. Before we can install packages we need to create and populate the keyring.

# Create some of the basic system folder structure
# You may run into `could not find or read directory` a lot when installing
# packages. Creating the dirs is often the solution.
mkdir "$USERROOT/etc"
mkdir -p $USERROOT/var/lib/pacman

# Copy the pacman config file from the original system
pacman_conf="$USERROOT/etc/pacman.conf"
cp /etc/pacman.conf "$pacman_conf"

# Create the keyring directory
gpgdir="$USERROOT/etc/pacman.d/gnupg"
mkdir -p "$gpgdir"

# Initialize the keyring
sudo pacman-key --gpgdir "$gpgdir" --conf "$pacman_conf" --init

# Populate the keyring
sudo pacman-key --gpgdir "$gpgdir" --conf "$pacman_conf" --populate archlinux

Note: despite running in the userspace root, pacman and pacman-key still need to run as root.

Aside: Pacman Aliases

It gets tedious running pacman -r "$USERROOT" --gpgdir... every time. I’d recommend adding it as an alias in .bashrc. I’ll be using this alias going forward.

alias pacman_="sudo pacman -r $USERROOT --gpgdir $USERROOT/etc/pacman.d/gnupg"

3. Sync Pacman

Before we can install packages we need to sync pacman with the remote repositories.

pacman_ -Sy

4. Install Core Utils

Our “system” is tabula rasa so we need some basic Linux utils. Our shell still has the real /usr/bin and /bin in it’s path and will try to find executables there, but some executables like pacman will try to resolve from the user root.

I’m using the list from Arch wiki/core_utilities

pacman_ -S coreutils tar less findutils diffutils grep sed gawk util-linux 
procps-ng

5. Update PATHs

In order for our shell to “see” our newly installed executables and libraries, we need to update our PATH. In $HOME/.bashrc you may see a line like export PATH=$PATH. If not, create it. Then append our new directories to it, like so:

export USERROOT="$HOME/.root"
export PATH=$PATH:"$USERROOT/usr/bin"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"$USERROOT/lib":"$USERROOT/lib64"

Library Path

A note on changing LD_LIBRARY_PATH: this is probably the only fragile part of the entire scheme. If our userroot has the same libraries as our system root, system executables could end up resolving libraries from our userroot and if the library versions differ it could cause errors. However, I think this is unlikely; the Steam Deck OS image is unlikely to fall very far behind our user root and by using LD_LIBRARY_PATH we’ve limited this change in library resolution to executables ran from the shell.

5. Install Packages

We’re ready to install whatever we want! The Steam Deck already has zsh installed but since that’s the first thing I install on a new system, I’ll start with that.

pacman_ -S zsh

Caveats

Many executables will still try to resolve resources from the real system root and I can’t promise that every tool will work perfectly. The next step would probably be using chroot to run executables under the userspace root. However, most executables will have arguments to change where they resolve resources.