Skip to content

Instantly share code, notes, and snippets.

@tdegrunt
Forked from Kethen/readme.md
Created January 4, 2023 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tdegrunt/9e64f4f62b2cc52c20c450e83d9aefbf to your computer and use it in GitHub Desktop.
Save tdegrunt/9e64f4f62b2cc52c20c450e83d9aefbf to your computer and use it in GitHub Desktop.
So steam deck recovery image dropped, let's boot it (sorta) (non amd hardware)

Booting the Steam Deck recovery image

https://help.steampowered.com/en/faqs/view/1B71-EDF2-EB6D-2BB3

SteamOS runs a custom grub to cater it's needs for it's A/B partition design. So far the said custom grub does not boot for me on ovmf/intel uefi (maybe it boots on amd? some said they managed to just rufus the image and boot it)

skip to https://gist.github.com/Kethen/698cfa8cf387e131ebd36fbfbfe9272e#gamescope-and-non-amd-gpu if it just boots for you

Upon closer inspection the official bootloader does load some kind of amd firmware before booting the kernel

Let's boot it anyway with our own grub with the following template grub config. One way to utilize this config is to prepare a livecd of fedora, then swap out the grub config with the template

Or just wait for the official release to drop, it's a bit of a tinker, and you can lose data if you do something wrong

DO NOT BOTHER ANYONE AT VALVE FOR ANYTHING BREAKING, THEY MADE IT CLEAR THAT THE RECOVERY IMAGE IS ONLY FOR STEAM DECK

image image image image image

set default="0"

function load_video {
  insmod efi_gop
  insmod efi_uga
  insmod video_bochs
  insmod video_cirrus
  insmod all_video
}

load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
insmod btrfs

set timeout=60
### END /etc/grub.d/00_header ###

set STEAMOS_ROOT_A=d9b54a83-c3aa-479f-b630-8dac41101a77
set STEAMOS_ROOT_B=80d16092-c110-4c59-b932-90f7f31e330a
set STEAMOS_ROOT_I=d44dbdb2-ee1a-4b33-9e2e-299bbdd4052e

# uuid probe is too late for partset
#set STEAMOS_EFI_A=C03D-6B8A
#set STEAMOS_EFI_B=C03E-62FA

set STEAMOS_EFI_A=/dev/sdb2
set STEAMOS_EFI_B=/dev/sdb3
set STEAMOS_EFI_I=/dev/sdc2

menuentry 'SteamOS A' {
        search --no-floppy --set=root -u $STEAMOS_ROOT_A
        linuxefi /boot/vmlinuz-linux-neptune console=tty1 rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 rd.systemd.gpt_auto=no loglevel=3 plymouth.ignore-serial-consoles amd_iommu=off amdgpu.gttsize=8128 spi_amd.speed_dev=1 audit=0 rd.steamos.efi=$STEAMOS_EFI_A
        initrdefi  /boot/initramfs-linux-neptune.img
}

menuentry 'SteamOS B' {
        search --no-floppy --set=root -u $STEAMOS_ROOT_B
        linuxefi /boot/vmlinuz-linux-neptune console=tty1 rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 rd.systemd.gpt_auto=no loglevel=3 plymouth.ignore-serial-consoles amd_iommu=off amdgpu.gttsize=8128 spi_amd.speed_dev=1 audit=0 rd.steamos.efi=$STEAMOS_EFI_B
        initrdefi  /boot/initramfs-linux-neptune.img
}

menuentry 'SteamOS installer' {
        search --no-floppy --set=root -u $STEAMOS_ROOT_I
        linuxefi /boot/vmlinuz-linux-neptune console=tty1 rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 rd.systemd.gpt_auto=no loglevel=3 plymouth.ignore-serial-consoles amd_iommu=off amdgpu.gttsize=8128 spi_amd.speed_dev=1 audit=0 rd.steamos.efi=$STEAMOS_EFI_I
        initrdefi  /boot/initramfs-linux-neptune.img
}

Booting the recovery image itself

During SteamOS boot process, a uuid partition map is loaded from it's EFI partition. The said partition has to be supplied by boot arg rd.steamos.efi=

The dracut script itself supports UUID= prefix for targetting /dev/disk/by-uuid devices, but the script seems to run before /dev/disk/by-uuid is even populated. On my test vm, I was using the 3rd sata drive, so STEAMOS_EFI_I is set to /dev/sdc2

...
set STEAMOS_EFI_I=/dev/sdc2
...

For future images you might also need to update STEAMOS_ROOT_I, on linux distros, you can inspect the UUIDs with sudo blkid

If the recovery image is not on a physical drive, do the following before

$ sudo losetup /dev/loop255 steamdeck-recovery-1.img
$ sudo partprobe /dev/loop255
$ sudo blkid

Now boot using the SteamOS Installer entry. If that does not work and a recovery shell shows up, manually mount the efi partition

# blkid
...
/dev/sdc1: LABEL_FATBOOT="esp" LABEL="esp" UUID="366C-7CF9" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="esp" PARTUUID="4f4a5642-bbb0-4162-9f77-827e81af737a"
/dev/sdc2: LABEL_FATBOOT="efi" LABEL="efi" UUID="3673-7A93" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="efi-A" PARTUUID="6161ccf4-54e6-4610-8ee1-b66b7a5a734b"
/dev/sdc3: LABEL="rootfs" UUID="d44dbdb2-ee1a-4b33-9e2e-299bbdd4052e" UUID_SUB="c23c5a68-0d00-4767-a75a-8cdf46cfea92" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="rootfs-A" PARTUUID="4c16321f-dc8c-4bb4-b4df-9232d6fdfe79"
/dev/sdc4: LABEL="var" UUID="55417ed4-ce01-4168-b412-de0198424430" BLOCK_SIZE="1024" TYPE="ext4" PARTLABEL="var-A" PARTUUID="5e1d137a-7a8b-41bc-8e8b-a9f7acbbe1ac"
/dev/sdc5: LABEL="home" UUID="cfdb4c1f-4d09-471d-bd1b-b1119d846ddf" BLOCK_SIZE="4096" TYPE="ext4" PARTLABEL="home" PARTUUID="2c5c3267-4a56-43e6-a8fe-4d78fa874ca6"
...

Then mount the partition labeled efi-A, then let the boot process continue

# mount -o ro /dev/sdc2 /var/mnt
# exit

Once booted into the recovery image, you'll get a KDE Plasma desktop

Imaging SteamOS using the recovery image

Now we can use the official repair script to image steamos onto another drive

You'd have to modify tools/repair_device.sh in your home directory to target a drive, eg. nano ~/tools/repair_device.sh in konsole

...
DISK=/dev/nvme0n1
DISK_SUFFIX=p
...

The above section was intended for imaging SteamOS onto /dev/nvme0n1, with partitions named /dev/nvme0n1p1, /dev/nvme0n1p2...

First of all, check sudo blkid and lsblk to locate your drive

If you plan to image on your first nvme device, you can likely keep that section unchanged.

If you plan to image on other nvme devices, you'd only need to change DISK=, for exmaple, DISK=nvme0n2 for the second namespace of the first nvme, or DISK=nvme1n1 for the first namespace of the second nvme.

If you plan to image on a sata drive, below is an exampe for /dev/sdb, with partitions named /dev/sdb1, /dev/sdb2...

...
DISK=/dev/sdb
DISK_SUFFIX=""
...

After that, run ./tools/repair_reimage.sh in konsole and let the disk imaging happen

You might want to press Cancel at the end of the process so that you can modify your grub configuration

Booting partition A

Once imaging is over, you'll find a bunch of new partitions added to your target drive, your UUIDs will be different from mine!

Change sdb in the blow command to the disk you have imaged to

$ sudo blkid | grep sdb | sort
/dev/sdb1: SEC_TYPE="msdos" LABEL_FATBOOT="esp" LABEL="esp" UUID="C03C-376D" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="esp" PARTUUID="60aa4425-88b7-5f41-95cc-d378b74fe317"
/dev/sdb2: SEC_TYPE="msdos" LABEL_FATBOOT="efi" LABEL="efi" UUID="C03D-6B8A" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="efi-A" PARTUUID="cc41bd29-493f-7f45-8cf1-0aede4dec1ff"
/dev/sdb3: SEC_TYPE="msdos" LABEL_FATBOOT="efi" LABEL="efi" UUID="C03E-62FA" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="efi-B" PARTUUID="dd4e8089-4521-424a-a78c-5ea69a8675d2"
/dev/sdb4: LABEL="rootfs" UUID="d9b54a83-c3aa-479f-b630-8dac41101a77" UUID_SUB="c23c5a68-0d00-4767-a75a-8cdf46cfea92" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="rootfs-A" PARTUUID="fd5d0e43-e467-c443-8cfb-4dc086894ca2"
/dev/sdb5: LABEL="rootfs" UUID="85bac642-d35f-4b85-bd5b-4df56ae56308" UUID_SUB="32550c6d-819f-4c22-b2db-fb4cf890eb42" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="rootfs-B" PARTUUID="3bdf2873-f9e2-014d-a5b5-7708082ce56c"
/dev/sdb6: LABEL="var" UUID="4c51161f-a65d-416a-a2d7-6eb1c1af6f4b" BLOCK_SIZE="1024" TYPE="ext4" PARTLABEL="var-A" PARTUUID="d59357b1-4e45-444a-af07-8c4f8f2bd3fe"
/dev/sdb7: LABEL="var" UUID="9849f222-6348-4dc6-b7fa-65fb447779bd" BLOCK_SIZE="1024" TYPE="ext4" PARTLABEL="var-B" PARTUUID="5a1a22ab-e75d-fd4e-8a10-01d9233761aa"
/dev/sdb8: LABEL="home" UUID="40adf72c-90f7-43fb-8f2f-982bdacbd546" BLOCK_SIZE="4096" TYPE="ext4" PARTLABEL="home" PARTUUID="704e1316-750c-3848-b020-13fd563b655e"

You'll have to update the grub config template to the radom UUID. Look for the partition labeled rootfs-A on the disk, copy the UUID field

...
set STEAMOS_ROOT_A=d9b54a83-c3aa-479f-b630-8dac41101a77
...

You'll also have to update the efi partition information. Look for the partition labeled efi-A, copy the disk device path

...
set STEAMOS_EFI_A=/dev/sdb2
...

Now the SteamOS A entry should boot into SteamOS. However, please read the next sections before proceeding

Updates

Successfully booting into SteamOS UI, once internet connection is configured, it'll attempt an update. The update will be installed onto B if you're booting A, vice versa. Once an update happen, STEAMOS_ROOT_A or STEAM_ROOT_B has to be updated in grub before booting. Updates will also appear to have failed. Disregard the failure, update the ROOTFS uuid and boot it.

The rule of thumb is to update STEAMOS_ROOT_B in grub then boot B after updating from STEAMOS_ROOT_A, and vice versa. Updates are installed to the alternative root partition.

Gamescope and non AMD GPU

Gamescope is used as a compositor in game console UI https://github.com/Plagman/gamescope

If gamescope cannot start, one would just get a black screen

Gamescope currently has issues with Intel GPUs due to driver problems. You'll have to install older mesa packages and downgrade gamescope. See ValveSoftware/gamescope#392

Gamescope currently does not work on Nvidia propietary drivers, see ValveSoftware/gamescope#151

Read the following sections regarding modifying the rootfs partition, as well as booting directly into Plasma instead of Steam

Boot to Plasma, modifying rootfs partitions

To boot directly to Plasma, you'll have to modify the SteamOS install from another linux install. The SteamOS recovery image will do just fine for that

First mount the rootfs you would like to boot to writable, for example, rootfs-A

$ sudo blkid
...
/dev/sdb4: LABEL="rootfs" UUID="d9b54a83-c3aa-479f-b630-8dac41101a77" UUID_SUB="c23c5a68-0d00-4767-a75a-8cdf46cfea92" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="rootfs-A" PARTUUID="fd5d0e43-e467-c443-8cfb-4dc086894ca2"
...
$ sudo mount /dev/sdb4 /mnt
$ sudo btrfs property set -t subvol /mnt ro false

After that modify /mnt/etc/sddm.conf.d/steamos.conf

#Session=gamescope-wayland.desktop
Session=plasmawayland.desktop

Then boot install A

To modify the active partition once booted, first set a password on the deck user

$ passwd

then

$ sudo mount -o remount,rw /
$ sudo btrfs property set -t subvol / ro false

NOTE THAT UPDATES REMOVE ALL MODIFICATIONS INVOLVING PACKAGES/ROOTFS, YOU WILL HAVE TO REDO THEM AFTER UPDATE

Plasma orientation

Plasma was hard coded to have a right rotation for Steamdeck

To remove that, modify /mnt/usr/bin/jupiter-plasma-bootstrap externally, or /usr/bin/jupiter-plasma-bootstrap if booted

Find the below lines and comment them out with #

#kscreen-doctor output.eDP.rotation.right \
#  || kscreen-doctor output.eDP-1.rotation.right \
#  || kscreen-doctor output.1.rotation.right \
#  || true

Downgrade gamescope and mesa for Intel GPU

Once booted, with rootfs already modifiable

First change /etc/pacman.conf to allow arch packages

...
[extra]
Include = /etc/pacman.d/mirrorlist
SigLevel = Never
...
[multilib]
Include = /etc/pacman.d/mirrorlist
SigLevel = Never
...

Then downgrade gamescope and install Intel mesa

$ sudo pacman -S extra/mesa extra/vulkan-intel multilib/lib32-mesa multilib/lib32-vulkan-intel holo/gamescope

Now you can revert boot to Plasma and boot into gamescope steam

Gamescope Steam resolution

Look for -w 1280 -h 800 in /usr/bin/gamescope-session, it is a bit finicky but you can probably change your resolution there changing it to -w <screen width> -h <screen height>. If that does not work, you can force scale it with -W <screen width> -H <screen height>

If scaling is involved, you might want to remove --max-scale 2

Enable ssh connection

First read the boot to Plasma section, or go to desktop mode from Steam, then fire up konsole

$ sudo systemctl enable sshd

The deck user needs a password for remote login, as well as sudo

$ passwd

On another machine

$ ssh deck@steam_deck_ip_address

Intel GPU (i915) with buggy wayland

If downgrading game scope and adding intel mesa did not work, there's a chance that it can still start gamescope under xorg. To do so, first install xorg drivers for intel

$ sudo pacman -S xf86-video-intel

After that make a xorg session from the wayland session

$ sudo cp /usr/share/wayland-sessions/gamescope-wayland.desktop /usr/share/xsessions/gamescope-xorg.desktop 

Then set sddm to launch the xorg session by changing /etc/sddm.conf.d/steamos.conf

...
#Session=gamescope-wayland.desktop
Session=gamescope-xorg.desktop
...

Change gamescope-wayland.desktop to gamescope-xorg.desktop in /usr/bin/steamos-session-select

...
  gamescope)
    #session_launcher="gamescope-wayland.desktop"
    session_launcher="gamescope-xorg.desktop"
  ;;
...

There's a chance that such hardware is really slow, so change /usr/bin/gamescope-session so that it does not fail launching

...
gamescope -w ...
gamescope_pid="$!"
sleep 5
if read -r -t 3 response_x_display response_wl_display <> "$socket"; then
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment